Performance and TSelectorDraw

we would appreciate some help to improve the performance of our code. A short description of the problem:

We are using root version 5.22 and TTrees containing several std:vector of variable size (typically of size less than 10).

We create histograms using TSelectorDraw in the following way:

TSelectorDraw* thisSelector = new TSelectorDraw();
TList* input = new TList();
input->Add(new TNamed(“varexp”,varexp));
input->Add(new TNamed(“selection”,selection));

where “varexp” denotes the variable in the tree and histogram to be filled, such as:

“selection” is a string containing cut statements such as
jetPt>30 && TMath::Abs(jetEta)<2.4 && triggerHLTJet15U==1 && 3dDistance>-0.5

where jetPt, jetEta, etc. are again std::vectors<> of same length.

The TTree is then processed with something like:

TFile* thisFile = TFile::Open( … );
TTree* thisTree = (TTree*)thisFile->Get(“Events”);
Long64_t nentries = thisTree->GetEntries();

Trees typically contain several millions of events and the program runs several hours at 100% CPU which is not satisfactory.

The profiler (gprof) tells us that most of the CPU time is spent in TSelectorDraw::Process.

Do you have any hints or recommendations how to increase performance? Would a manual event loop or a different data structure (fixed size arrays instead of vectors) improve anything?

Thanks for your help in advance,

Simply create a TSelector class with the standard functions Begin, Process, Terminate and implement your selection as pure C++ code. Run your selector with ACLIC.
Concerning the data model, if your std::vector are in general less than 10 entries, I suggest to replace them with simple C style arrays like
int fN; //vector length
float *x; //[fN]
float *y; //[fN]

In this way you will likely gain at least a factor 2 compared to std::vector and a better compression factor.


Dear Rene,
thanks for your suggestion. I will try switching to C style arrays.

Do I understand correctly that you are suggesting to implement our cuts as pure C++ code? Unfortunately this is not an option, we sometimes need quite complex cut queries and need high flexibility. Implementing a separate TSelector for all use cases would be too much.

We could implement a TSelector and compile the cuts using TTreeFormula (or similar), but as I understand this would not be too different from using TSelectorDraw, which does the same thing, right?

thanks again for your help.

up to you, anything going via TTreeFormula will be much slower than direct C++ code in your selector.
And in your selector you can easily branch to different algorithms/selections when required.