bench.cxx

Go to the documentation of this file.
00001 // this test program compares the I/O performance obtained with
00002 // all STL collections of objects or pointers to objects and also
00003 // Root collection class TClonesArray.
00004 // Trees in compression and non compression mode are created for each
00005 // of the following cases:
00006 //  -STLcollection<THit>
00007 //  -STLcollection<THit*>
00008 //  -TClonesArray(TObjHit) in no split mode
00009 //  -TClonesArray(TObjHit) in split mode
00010 // where:
00011 //  THit is a class not derived from TObject
00012 //  TObjHit derives from TObject and THit
00013 //
00014 //  run with
00015 //     bench
00016 //   or
00017 //     bench -m   to stream objects memberwise
00018 //
00019 // The test prints a summary table comparing performances for all above cases
00020 // (CPU, file size, compression factors).
00021 // Reference numbers on a Pentium IV 2.4 Ghz machine are given as reference.
00022 //      Authors:  Rene Brun, Markus Frank
00023 
00024 #include "TROOT.h"
00025 #include "TClonesArray.h"
00026 #include "TStopwatch.h"
00027 #include "TFile.h"
00028 #include "TTree.h"
00029 #include "TSystem.h"
00030 #include "TStreamerInfo.h"
00031 
00032 #include "TBench.h"
00033 
00034 struct TBenchData {
00035    TBenchData() : cp1(0), nbytes1(0), cp2w(0), cp2r(0), cx3(0), nbytes3(0), cp3w(0), cp3r(0)  {}
00036    TBenchData(const char *name, Double_t i_cp1, Float_t i_cx3, Long64_t i_nbytes1, Long64_t i_nbytes3, Double_t i_cp2w, Double_t i_cp3w, Double_t i_cp2r, Double_t i_cp3r) 
00037      :  fName(name), cp1(i_cp1), nbytes1(i_nbytes1), cp2w(i_cp2w), cp2r(i_cp2r), cx3(i_cx3), nbytes3(i_nbytes3), cp3w(i_cp3w), cp3r(i_cp3r) {}
00038    TString fName;
00039    Double_t rt1;
00040    Double_t cp1;
00041    Float_t cx;
00042    Long64_t nbytes1;
00043    Double_t rt2w;
00044    Double_t cp2w;
00045    Double_t rt2r;
00046    Double_t cp2r;
00047    Float_t cx3;
00048    Long64_t nbytes3;
00049    Double_t rt3w;
00050    Double_t cp3w;
00051    Double_t rt3r;
00052    Double_t cp3r;
00053    
00054    Double_t cptot() { return cp1 + cp2w + cp2r + cp3w + cp3r; }
00055 };
00056 
00057 template <class TGen> TBenchData runTest(const char *name, int nevents, int nhits, int splitlevel)
00058 {
00059    static TStopwatch timer;
00060 
00061    TBenchData data;
00062    data.fName = name;
00063    
00064    timer.Start();
00065    TGen *STLhit = new TGen(nhits);
00066    STLhit->MakeTree(0,nevents,0,0,data.cx);
00067    timer.Stop();
00068    data.rt1 = timer.RealTime();
00069    data.cp1 = timer.CpuTime();
00070    printf("1 %-26s  : RT=%6.2f s  Cpu=%6.2f s\n",data.fName.Data(),data.rt1,data.cp1);
00071 
00072    timer.Start(kTRUE);
00073    data.nbytes1 = STLhit->MakeTree(1,nevents,0,splitlevel,data.cx);
00074    timer.Stop();
00075    data.rt2w = timer.RealTime();
00076    data.cp2w = timer.CpuTime();
00077    printf("2 %-26s w: RT=%6.2f s  Cpu=%6.2f s, size= %8lld bytes, cx=%5.2f\n",data.fName.Data(),data.rt2w,data.cp2w,data.nbytes1,data.cx);
00078    
00079    timer.Start(kTRUE);
00080    STLhit->ReadTree();
00081    timer.Stop();
00082    data.rt2r = timer.RealTime();
00083    data.cp2r = timer.CpuTime();
00084    printf("3 %-26s r: RT=%6.2f s  Cpu=%6.2f s\n",data.fName.Data(),data.rt2r,data.cp2r);
00085    
00086    timer.Start(kTRUE);
00087    data.nbytes3 = STLhit->MakeTree(1,nevents,1,splitlevel,data.cx3);
00088    timer.Stop();
00089    data.rt3w = timer.RealTime();
00090    data.cp3w = timer.CpuTime();
00091    printf("4 %-26s w: RT=%6.2f s  Cpu=%6.2f s, size= %8lld bytes, cx=%5.2f\n",data.fName.Data(),data.rt3w,data.cp3w,data.nbytes3,data.cx3);
00092    
00093    timer.Start(kTRUE);
00094    STLhit->ReadTree();
00095    timer.Stop();
00096    data.rt3r = timer.RealTime();
00097    data.cp3r = timer.CpuTime();
00098    printf("5 %-26s r: RT=%6.2f s  Cpu=%6.2f s\n",data.fName.Data(),data.rt3r,data.cp3r);
00099    
00100    delete STLhit;
00101    return data;
00102 }
00103 
00104 template <class TGen> TBenchData runTest(const char *name, int nevents, int nhits, int splitlevel, Double_t &cptot, vector<TBenchData> &results)
00105 {
00106    TBenchData data = runTest<TGen>( name, nevents, nhits, splitlevel);
00107    cptot += data.cptot();
00108    results.push_back( data );
00109    return data;
00110 }
00111 
00112 int main(int argc, char **argv)
00113 {
00114    bool writereferences = false;   
00115    bool memberwise = false;
00116    
00117    TVirtualStreamerInfo::SetStreamMemberWise(kFALSE);
00118    // by default stream objects objectwise
00119    // if program option "-m" is specified, stream memberwise
00120    for(int a=1; a<argc; ++a) {
00121       if (strstr(argv[a],"-m")) {
00122          TVirtualStreamerInfo::SetStreamMemberWise(kTRUE);
00123          printf("bench option -m specified. Streaming objects memberwise\n");
00124          memberwise = true;
00125       } else if (strstr(argv[a],"-r")) {
00126          writereferences = true;
00127       }
00128    }
00129    int nhits       = 1000;
00130    int nevents     = 400;
00131    
00132    Double_t cptot = 0;
00133    
00134    //delete temp file used for the benchmark
00135    gSystem->Unlink(Form("%s/bench.root",gSystem->TempDirectory()));
00136    
00137    vector<TBenchData> results;
00138    vector<TBenchData> references;
00139    references.push_back( TBenchData( "vector<THit> level=99",   0.44,   5.37, 39724266, 7392775,   0.96,   2.15,   0.32,   0.73 ) );
00140    references.push_back( TBenchData( "vector<THit> level= 0",   0.29,   3.76, 42053455, 11177799,   0.85,   3.22,   0.68,   0.93 ) );
00141    references.push_back( TBenchData( "vector<THit> level= 0 MW",   0.28,   4.96, 39654255, 7997901,   0.63,   1.91,   0.33,   0.52 ) );
00142    references.push_back( TBenchData( "list<THit> level=99",   0.36,   5.37, 39724301, 7393378,   0.75,   2.33,   0.50,  0.64 ) );
00143    references.push_back( TBenchData( "list<THit> level= 0",   0.37,   3.76, 42053474, 11177716,   0.94,   2.96,   0.64,   1.02 ) );
00144    references.push_back( TBenchData( "list<THit> level= 0 MW",   0.37,   4.96, 39654274, 7998366,   0.76,   2.26,   0.37,   0.63 ) );
00145    references.push_back( TBenchData( "deque<THit> level=99",   0.38,   5.37, 39724311, 7392970,   0.70,   2.01,   0.30,   0.79 ) );
00146    references.push_back( TBenchData( "deque<THit> level= 0",   0.38,   3.76, 42053480, 11177240,   0.95,   2.70,   0.81,   0.97 ) );
00147    references.push_back( TBenchData( "deque<THit> level= 0 MW",   0.37,   4.96, 39654280, 7998569,   0.76,   2.07,   0.42,   0.88 ) );
00148    references.push_back( TBenchData( "set<THit> level=99",   0.41,   6.21, 39724292, 6396267,   0.81,   2.09,   0.62, 0.71 ) );
00149    references.push_back( TBenchData( "set<THit> level= 0",   0.41,   4.39, 42053469, 9573788,   0.99,   2.65,   0.89, 1.10 ) );
00150    references.push_back( TBenchData( "set<THit> level= 0 MW",   0.41,   5.79, 39654269, 6851326,   0.85,   1.62,   0.45,   0.69 ) );
00151    references.push_back( TBenchData( "multiset<THit> level=99",   0.44,   6.21, 39724346, 6396195,   0.83,   2.25,   0.46,   0.71 ) );
00152    references.push_back( TBenchData( "multiset<THit> level= 0",   0.43,   4.39, 42053503, 9573512,   1.04,   2.83,   0.76,   1.09 ) );
00153    references.push_back( TBenchData( "multiset<THit> level= 0 MW",   0.44,   5.79, 39654303, 6851637,   0.88,   2.03, 0.62,   0.69 ) );
00154    references.push_back( TBenchData( "map<THit> level=99",   0.48,   5.26, 41335814, 7861427,   0.91,   2.39,   0.67, 0.77 ) );
00155    references.push_back( TBenchData( "map<THit> level= 0",   0.48,   3.84, 43653478, 11357815,   1.08,   2.69,   1.14,  1.19 ) );
00156    references.push_back( TBenchData( "map<THit> level= 0 MW",   0.48,   3.68, 43655963, 11866052,   1.18,   2.94,   1.07,   1.17 ) );
00157    references.push_back( TBenchData( "multimap<THit> level=99",   0.49,   5.26, 41335869, 7861144,   0.90,   2.52,   0.48,   0.78 ) );
00158    references.push_back( TBenchData( "multimap<THit> level= 0",   0.49,   3.84, 43653510, 11358500,   1.09,   2.72,   1.13,   1.18 ) );
00159    references.push_back( TBenchData( "multimap<THit> level= 0 MW",   0.48,   3.68, 43655998, 11866816,   1.15,   2.95,  1.04,   1.17 ) );
00160    references.push_back( TBenchData( "vector<THit*> level=25599",   0.25,   5.14, 40137890, 7806511,   0.57,   1.78,0.33,   0.87 ) );
00161    references.push_back( TBenchData( "list<THit*> level=25599",   0.33,   5.14, 40137936, 7806412,   0.63,   2.13,   0.42,   0.69 ) );
00162    references.push_back( TBenchData( "deque<THit*> level=25599",   0.31,   5.14, 40137945, 7806520,   0.67,   1.89,   0.35,   0.88 ) );
00163    references.push_back( TBenchData( "set<THit*> level=25599",   0.38,   5.74, 40137925, 6990746,   0.72,   2.20,   0.70,   0.95 ) );
00164    references.push_back( TBenchData( "multiset<THit*> level=25599",   0.36,   5.85, 40137981, 6865586,   0.73,   2.17,  0.68,   0.86 ) );
00165    references.push_back( TBenchData( "map<THit*> level=99",   0.37,   3.71, 46864802, 12643706,   1.28,   3.24,   1.34,   2.11 ) );
00166    references.push_back( TBenchData( "multimap<THit*> level=99",   0.36,   3.71, 46864850, 12642782,   1.28,   3.20,1.38,   1.58 ) );
00167    references.push_back( TBenchData( "vector<THit*> level=99 (NS)",   0.24,   3.72, 45257044, 12170238,   1.08,   3.05,   1.43,   1.44 ) );
00168    references.push_back( TBenchData( "list<THit*> level=99 (NS)",   0.30,   3.72, 45257088, 12169539,   1.14,   2.88, 1.45,   1.49 ) );
00169    references.push_back( TBenchData( "deque<THit*> level=99 (NS)",   0.32,   3.72, 45257098, 12167790,   1.16,   2.69,  1.41,   1.44 ) );
00170    references.push_back( TBenchData( "set<THit*> level=99 (NS)",   0.38,   4.29, 45257081, 10550593,   1.23,   3.01,1.28,   2.14 ) );
00171    references.push_back( TBenchData( "multiset<THit*> level=99 (NS)",   0.45,   4.28, 45257136, 10572288,   1.27,   3.03,   1.61,   1.50 ) );
00172    references.push_back( TBenchData( "TClonesArray(TObjHit) level= 0",   0.28,   4.96, 39666751, 8006156,   0.55,   1.76,   0.16,   0.64 ) );
00173    references.push_back( TBenchData( "TClonesArray(TObjHit) level=99",   0.37,   5.37, 39722797, 7392577,   0.55,   2.07,   0.17,   0.46 ) );    
00174 
00175    /// STL VECTOR
00176    runTest<TSTLhit>( "vector<THit> level=99", nevents, nhits, 99, cptot, results );
00177    /// STL VECTOR not split.
00178    runTest<TSTLhit>( "vector<THit> level= 0", nevents, nhits,  0, cptot, results );
00179    
00180    /// STL VECTOR not split, member wise mode
00181    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00182    runTest<TSTLhit>( "vector<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00183    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00184    
00185    // STL list
00186    runTest<TSTLhitList>( "list<THit> level=99", nevents, nhits, 99, cptot, results );
00187    runTest<TSTLhitList>( "list<THit> level= 0", nevents, nhits,  0, cptot, results );
00188    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00189    runTest<TSTLhitList>( "list<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00190    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00191    
00192    // STL DEQUE
00193    runTest<TSTLhitDeque>( "deque<THit> level=99", nevents, nhits, 99, cptot, results );
00194    runTest<TSTLhitDeque>( "deque<THit> level= 0", nevents, nhits,  0, cptot, results );
00195    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00196    runTest<TSTLhitDeque>( "deque<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00197    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00198    
00199    // STL SET
00200    runTest<TSTLhitSet>( "set<THit> level=99", nevents, nhits, 99, cptot, results );
00201    runTest<TSTLhitSet>( "set<THit> level= 0", nevents, nhits,  0, cptot, results );
00202    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00203    runTest<TSTLhitSet>( "set<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00204    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00205    
00206    // STL MULTI SET
00207    runTest<TSTLhitMultiset>( "multiset<THit> level=99", nevents, nhits, 99, cptot, results );
00208    runTest<TSTLhitMultiset>( "multiset<THit> level= 0", nevents, nhits,  0, cptot, results );
00209    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00210    runTest<TSTLhitMultiset>( "multiset<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00211    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00212    
00213    // STL map
00214    runTest<TSTLhitMap>( "map<THit> level=99", nevents, nhits, 99, cptot, results );
00215    runTest<TSTLhitMap>( "map<THit> level= 0", nevents, nhits,  0, cptot, results );
00216    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00217    runTest<TSTLhitMap>( "map<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00218    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00219    
00220    // STL multimap
00221    runTest<TSTLhitMultiMap>( "multimap<THit> level=99", nevents, nhits, 99, cptot, results );
00222    runTest<TSTLhitMultiMap>( "multimap<THit> level= 0", nevents, nhits,  0, cptot, results );
00223    memberwise = TVirtualStreamerInfo::SetStreamMemberWise(true);
00224    runTest<TSTLhitMultiMap>( "multimap<THit> level= 0 MW", nevents, nhits,  0, cptot, results );
00225    TVirtualStreamerInfo::SetStreamMemberWise(memberwise);
00226    
00227    //__________________________________________________________________________
00228    //
00229    //testing STL vector of pointers to THit
00230    runTest<TSTLhitStar>( "vector<THit*> level=25599", nevents, nhits, 25599, cptot, results );
00231    
00232    // STL list*
00233    runTest<TSTLhitStarList>( "list<THit*> level=25599", nevents, nhits, 25599, cptot, results );
00234    
00235    // STL DEQUE*
00236    runTest<TSTLhitStarDeque>( "deque<THit*> level=25599", nevents, nhits, 25599, cptot, results );
00237    
00238    // STL SET*
00239    runTest<TSTLhitStarSet>( "set<THit*> level=25599", nevents, nhits, 25599, cptot, results );
00240   
00241    // STL MULTI SET*
00242    runTest<TSTLhitStarMultiSet>( "multiset<THit*> level=25599", nevents, nhits, 25599, cptot, results );
00243    
00244    // STL MAP*
00245    runTest<TSTLhitStarMap>( "map<THit*> level=99", nevents, nhits, 99, cptot, results );
00246    
00247    // STL MULTIMAP*
00248    runTest<TSTLhitStarMultiMap>( "multimap<THit*> level=99", nevents, nhits, 99, cptot, results );
00249    
00250    //__________________________________________________________________________
00251    //
00252    //testing STL vector of pointers to THit (NOSPLIT)
00253    runTest<TSTLhitStar>( "vector<THit*> level=99 (NS)", nevents, nhits, 99, cptot, results );
00254    
00255    // STL list* (NOSPLIT)
00256    runTest<TSTLhitStarList>( "list<THit*> level=99 (NS)", nevents, nhits, 99, cptot, results );
00257    
00258    // STL DEQUE* (NOSPLIT)
00259    runTest<TSTLhitStarDeque>( "deque<THit*> level=99 (NS)", nevents, nhits, 99, cptot, results );
00260    
00261    // STL SET* (NOSPLIT)
00262    runTest<TSTLhitStarSet>( "set<THit*> level=99 (NS)", nevents, nhits, 99, cptot, results );
00263    
00264    // STL MULTI SET* (NOSPLIT)
00265    runTest<TSTLhitStarMultiSet>( "multiset<THit*> level=99 (NS)", nevents, nhits, 99, cptot, results );
00266    
00267    //___________________________________________________________________________
00268    //
00269    //testing TClonesArray of TObjHit deriving from THit
00270    runTest<TCloneshit>( "TClonesArray(TObjHit) level= 0", nevents, nhits,  0, cptot, results );
00271    runTest<TCloneshit>( "TClonesArray(TObjHit) level=99", nevents, nhits, 99, cptot, results );
00272 
00273    Double_t cpref = 195.43;
00274    Double_t rootmarks = cpref*800/cptot;
00275    
00276    for(unsigned int t=references.size(); t<results.size(); ++t) {
00277       references.push_back(TBenchData());
00278    }
00279    
00280    //print all results
00281    char line1[100], line2[100];
00282    printf("\n");
00283    printf("*******************************************************************************\n");
00284    sprintf(line1,"Comparing STL vector with TClonesArray: Root %-8s",gROOT->GetVersion());
00285    printf("*       %s                 *\n",line1);
00286    Bool_t UNIX = strcmp(gSystem->GetName(), "Unix") == 0;
00287    if (UNIX) {
00288       TString sp = gSystem->GetFromPipe("uname -a");
00289       sp.Resize(60);
00290       printf("*  SYS: %s\n",sp.Data());
00291       if (strstr(gSystem->GetBuildNode(),"Linux")) {
00292          sp = gSystem->GetFromPipe("lsb_release -d -s");
00293          printf("*  SYS: %s\n",sp.Data());
00294       }
00295       if (strstr(gSystem->GetBuildNode(),"Darwin")) {
00296          sp  = gSystem->GetFromPipe("sw_vers -productVersion");
00297          sp += " Mac OS X ";
00298          printf("*  SYS: %s\n",sp.Data());
00299       }
00300    } else {
00301       const char *os = gSystem->Getenv("OS");
00302       sprintf(line2,"Windows");
00303       if (!os) printf("*  Windows 95\n");
00304       else     printf("*  %s %s \n",os,gSystem->Getenv("PROCESSOR_IDENTIFIER"));
00305    }
00306    printf("*     Reference machine pcbrun4.cern.ch  RedHat Linux 7.3                     *\n");
00307    printf("*         (Pentium IV 2.4 Ghz 512 Mbytes RAM, IDE disk)                       *\n");
00308    printf("*           (send your results to rootdev@root.cern.ch)                       *\n");
00309    printf("*******************************************************************************\n");
00310    printf("* Time to fill the structures  (seconds)   Reference      cx      Reference   *\n");
00311    printf("*******************************************************************************\n");
00312    for(unsigned int t=0; t<results.size() && t<references.size(); ++t) {
00313       printf("* %-30s %6.2f       %5.2f     %5.2f       %5.2f     *\n",results[t].fName.Data(),results[t].cp1,references[t].cp1,results[t].cx3,references[t].cx3);
00314    }
00315    printf("*******************************************************************************\n");
00316    printf("* Size of file in bytes          comp 0    Reference    comp 1    Reference   *\n");
00317    printf("*******************************************************************************\n");
00318    for(unsigned int t=0; t<results.size() && t<references.size(); ++t) {
00319       printf("* %-30s %8lld   %8lld   %8lld  %8lld     *\n",results[t].fName.Data(),results[t].nbytes1,references[t].nbytes1,results[t].nbytes3,references[t].nbytes3);
00320    }
00321    printf("*******************************************************************************\n");
00322    printf("* Time to write in seconds       comp 0    Reference    comp 1    Reference   *\n");
00323    printf("*******************************************************************************\n");
00324    for(unsigned int t=0; t<results.size() && t<references.size(); ++t) {
00325       printf("* %-30s %6.2f      %6.2f    %6.2f      %6.2f     *\n",results[t].fName.Data(),results[t].cp2w,references[t].cp2w, results[t].cp3w, references[t].cp3w);
00326    }
00327    printf("*******************************************************************************\n");
00328    printf("* Time to read in seconds        comp 0    Reference    comp 1    Reference   *\n");
00329    printf("*******************************************************************************\n");
00330    for(unsigned int t=0; t<results.size() && t<references.size(); ++t) {
00331       printf("* %-30s %6.2f      %6.2f    %6.2f      %6.2f     *\n",results[t].fName.Data(),results[t].cp2r,references[t].cp2r,results[t].cp3r,references[t].cp3r);
00332    }
00333    printf("*******************************************************************************\n");
00334    printf("* Total CPU time              %8.2f    %8.2f                            *\n",cptot,cpref);
00335    printf("* Estimated ROOTMARKS         %8.2f      800.00                            *\n",rootmarks);
00336    printf("******************************************************************************\n");
00337    
00338    if (writereferences) {
00339       for(unsigned int t=0; t<results.size() && t<references.size(); ++t) {
00340          printf("references.push_back( TBenchData( \"%s\", %6.2f, %6.2f, %lld, %lld, %6.2f, %6.2f, %6.2f, %6.2f ) );\n",
00341                 results[t].fName.Data(),results[t].cp1,results[t].cx3,results[t].nbytes1,results[t].nbytes3,results[t].cp2w,results[t].cp3w,results[t].cp2r,results[t].cp3r);
00342       }
00343    }
00344    return 0;
00345 }

Generated on Tue Jul 5 15:14:47 2011 for ROOT_528-00b_version by  doxygen 1.5.1