// test performance of all vectors operations +,- and * // results on mactelm g++ 4.01 showing ROOT::Math performs best overall //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a v2 = v1/a v1 /= a // 0.59 0.57 0.58 0.56 0.69 0.7 1.65 1.64 2D // 0.79 0.79 0.78 0.8 0.97 0.95 1.85 1.84 3D // 1.07 1.07 1.07 1.07 1.32 1.31 1.72 1.71 4D // ROOT Physics Vector (TVector's): //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a // 4.4 0.97 4.41 0.96 4.43 1.13 2D // 5.44 1.25 5.48 1.24 6.12 1.46 3D // 17.65 7.32 17.65 7.35 10.25 7.79 4D // CLHEP Vector (HepVector's): //v3 = v1+v2 v2 += v1 v3 = v1-v2 v2 -= v1 v2 = a*v1 v1 *= a // 0.57 0.55 0.56 0.55 0.7 0.7 2D // 0.8 0.79 0.78 0.77 0.96 0.94 2.7 3.7 3D // 1.06 1.02 1.06 1.02 1.26 1.26 2.99 3.98 4D #include "TRandom2.h" #include "TStopwatch.h" #include #include #include #ifdef DIM_2 #ifdef USE_POINT #include "Math/Point2D.h" typedef ROOT::Math::XYPoint VecType; #elif USE_CLHEP #include "CLHEP/Vector/TwoVector.h" typedef Hep2Vector VecType; #elif USE_ROOT #include "TVector2.h" typedef TVector2 VecType; #else #include "Math/Vector2D.h" typedef ROOT::Math::XYVector VecType; #endif #ifndef USE_ROOT #define VSUM(v) v.x() + v.y() #else #define VSUM(v) v.X() + v.Y() #endif #elif DIM_3 // 3 Dimensions #ifdef USE_POINT #include "Math/Point3D.h" typedef ROOT::Math::XYZPoint VecType; #elif USE_CLHEP #include "CLHEP/Vector/ThreeVector.h" typedef Hep3Vector VecType; #elif USE_ROOT #include "TVector3.h" typedef TVector3 VecType; #else #include "Math/Vector3D.h" typedef ROOT::Math::XYZVector VecType; #endif #ifndef USE_ROOT #define VSUM(v) v.x() + v.y() + v.z() #else #define VSUM(v) v.X() + v.Y() + v.Z() #endif #else // default is 4D #undef USE_POINT #ifdef USE_CLHEP #include "CLHEP/Vector/LorentzVector.h" typedef HepLorentzVector VecType; #elif USE_ROOT #include "TLorentzVector.h" typedef TLorentzVector VecType; #else #include "Math/Vector4D.h" typedef ROOT::Math::XYZTVector VecType; #endif #ifndef USE_ROOT #define VSUM(v) v.x() + v.y() + v.z() + v.t() #else #define VSUM(v) v.X() + v.Y() + v.Z() + v.T() #endif #endif const int N = 1000000; template class TestVector { public: TestVector(); void Add(); void Add2(); void Sub(); void Sub2(); void Scale(); void Scale2(); void Divide(); void Divide2(); void PrintSummary(); private: std::vector vlist; std::vector scale; double fTime[10]; // timing results int fTest; }; template TestVector::TestVector() : vlist(std::vector(N) ), scale(std::vector(N) ), fTest(0) { // create list of vectors and fill them TRandom2 r(111); for (int i = 0; i< N; ++i) { #ifdef DIM_2 vlist[i] = Vector( r.Uniform(-1,1), r.Uniform(-1,1) ); #elif DIM_3 vlist[i] = Vector( r.Uniform(-1,1),r.Uniform(-1,1),r.Uniform(-1,1) ); #else // 4D vlist[i] = Vector( r.Uniform(-1,1),r.Uniform(-1,1),r.Uniform(-1,1), r.Uniform(2,10) ); #endif scale[i] = r.Uniform(0,1); } std::cout << "test using " << typeid(vlist[0]).name() << std::endl; } template void TestVector::Add() // normal addition { TStopwatch w; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 1; i< N; ++i) { Vector v3 = vlist[i-1] + vlist[i]; s += VSUM(v3); } } std::cout << "Time for v3 = v1 + v2 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Add2() { // self addition TStopwatch w; Vector v3; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 0; i< N; ++i) { v3 += vlist[i]; s += VSUM(v3); } } std::cout << "Time for v2 += v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Sub() { // normal sub TStopwatch w; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 1; i< N; ++i) { Vector v3 = vlist[i-1] - vlist[i]; s += VSUM(v3); } } std::cout << "Time for v3 = v1 - v2 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Sub2() { // self subtruction TStopwatch w; Vector v3; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 0; i< N; ++i) { v3 -= vlist[i]; s += VSUM(v3); } } std::cout << "Time for v2 -= v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Scale() { // normal multiply TStopwatch w; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 1; i< N; ++i) { Vector v3 = scale[i]*vlist[i]; s += VSUM(v3); } } std::cout << "Time for v2 = A * v1 :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Scale2() { // self scale TStopwatch w; Vector v3; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 0; i< N; ++i) { v3 = vlist[i]; v3 *= scale[i]; s += VSUM(v3); } } std::cout << "Time for v *= a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Divide() { // normal divide TStopwatch w; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 1; i< N; ++i) { Vector v3 = vlist[i]/scale[i]; s += VSUM(v3); } } std::cout << "Time for v2 = v1 / a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::Divide2() { // self divide TStopwatch w; Vector v3; w.Start(); double s = 0; for (int l = 0; l<100; ++l) { for (int i = 0; i< N; ++i) { v3 = vlist[i]; v3 /= scale[i]; s += VSUM(v3); } } std::cout << "Time for v /= a :\t" << w.RealTime() << "\t" << w.CpuTime() << std::endl; std::cout << "value " << s << std::endl << std::endl; fTime[fTest++] = w.CpuTime(); } template void TestVector::PrintSummary() { std::cout << "\nResults for " << typeid(vlist[0]).name() << std::endl; std::cout << " v3 = v1+v2" << " v2 += v1 " << " v3 = v1-v2" << " v2 -= v1 " << " v2 = a*v1 " << " v1 *= a " << " v2 = v1/a " << " v1 /= a " << std::endl; for (int i = 0; i < fTest; ++i) { std::cout << std::setw(8) << fTime[i] << " "; } std::cout << std::endl << std::endl; } int main() { TestVector t; #ifndef USE_POINT t.Add(); t.Add2(); t.Sub(); t.Sub2(); #endif t.Scale(); t.Scale2(); #ifndef USE_ROOT t.Divide(); t.Divide2(); #endif // summurize test t.PrintSummary(); }