[ROOT] Arbitrary access to tree entries VS sequential one

From: Valeri Tioukov (Valeri.Tioukov@na.infn.it)
Date: Fri May 10 2002 - 15:10:08 MEST


Hi rooters,

I noted that the arbitrary access to the tree entries is significantly slower
then the sequential ones.

May be it is an important feature of reading algorithm  and it not simple to
optimise, overwise it cold be useful to speed up.

In the applied script I tested 2 cases of access to the tree entries:

1) sequential
2) "arbitrary" (not really arbitrary in my test)

Test was done on the file Event.root with 20000 events generated with the
standard settings.

In case of reading only one branch fNtrack the output is:
20000 events:   Real time 0:0:3, CP time 3.380
20000 events:   Real time 0:0:40, CP time 40.330

so the second case is 12 times slower. In principle one could expect some
encrease of access time due to memory (disk) pages lists or similar effects.
But this could behave like a constant: 40-3 = 37.
Instead when I read more branches the ratio is even more havy:

20000 events:   Real time 0:0:6, CP time 6.110
20000 events:   Real time 0:2:19, CP time 139.130

ratio = 23, difference = 133

Regards,
Valeri

//--test1.C-------------------------------------------------------------------

// To start the test do:
//
// root [0] .L libEvent.so
// root [1] .L test1.C++
// root [2] init()
// root [3] sel()

#include "TTree.h"
#include "TFile.h"
#include "Event.h"
#include "TStopwatch.h"
#include "iostream.h"

TFile      *f = 0;
TTree      *chain =0;

void init()
{
  f = new TFile("Event.root");
  chain = (TTree*)f->Get("T");
}

void sel()
{
  Event *event = 0;

  //chain->SetBranchStatus("*",0);           // ratio 12
  //chain->SetBranchStatus("fNtrack",1);     //

  chain->SetBranchStatus("*",1);             // ratio 23
  chain->SetBranchStatus("fTracks*",0);      //

  chain->SetBranchAddress("event",&event);

  int entries = (int)(chain->GetEntries());
  int entries2 = entries/2;
  int counter;
  printf("chain has %d entries\n",entries);

  TStopwatch timer1;
  timer1.Start();
  counter=0;
  for(int i=0; i<entries; i++ ) {
    chain->GetEntry(i);
    counter++;
  }

  timer1.Stop();
  cout << counter<< " events: \t"; timer1.Print();

  int e1 = 200;
  int e2 = entries-200;

  TStopwatch timer2;
  timer2.Start();
  counter=0;
  for(int i=0; i<entries2; i++ ) {
    chain->GetEntry(e1);
    counter++;
    chain->GetEntry(e2);
    counter++;
  }
  timer2.Stop();
  cout << counter<< " events: \t"; timer2.Print();
}
//----------------------------------------------------------------



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:52 MET