In this context I/O
is decomposed in 3 parts:
-
raw I/O which read the bytes from the disk
-
(most often) decompressing
-
deserializing (transforming from the platform-independent format to the in-memory format).
-
is (usually) done through the
TTreeCache
cluster by cluster and when correctly configured fetch from the disk only the (entire compressed) basket of the branch used (heretraces_
which holds the size of thetrace
collection andtraces.SimSignal_X
. It can be tune to only read the basket containing the entries being used when this is known in advanced. -
This is done “just in time” when the data for a specific TTree entry is read.
Usually 2. is the dominant factor. Whether 1 or 3 is dominant depends on the speed of the disk and the complexity of the data. In you case the cost 1 and 3 might also be similar to the cost of just running TTree::Draw on the data (exclusive of the cost of the GetEntry
)
entries = t.Draw("traces[100].SimSignal_X", "", "goff")
vs
entries = t.Draw("traces[100].SimSignal_X", "Entry$==499", "goff")
TTree::Draw is not tuned to understand that the filter "Entry$==499"
reduce the number of entries actually used, so it request them all (read all the basket for the 2 branches for the whole file). It also need to evaluate the criteria all 1001 times.
A better way of writing the 2nd one is:
entries = t.Draw("traces[100].SimSignal_X", "", "goff", 1 /* # of entries */, 499 /* first entry */);
This should fetch from the disk only one basket per branch and execute the TTreeFormula only once.
entries = t.Draw("traces.SimSignal_X", "", "goff")
takes ~40 seconds, ~50 times longer then just traces[100].
Most likely this is the cost of filling the histograms (with 180x more entries) that becomes dominant.
Literally (pending unintended deficiencies) the only differences between Draw("traces.SimSignal_X")
and Draw("traces[100].SimSignal_X")
should be that for each entry Draw
loop 1000 time to copy the float out of the (uncompressed) buffer and call (in a slight more optimized/complex way than that but semantically equivalent) TH1F::Fill
in the first case and do that same loop 180*1000 times per entry in the 2nd case.
Try
entries = t.Draw("Sum$(traces.SimSignal_X)", "", "goff")
which should return only 1001 entries
and thus be more stable for your purpose and focus on the I/O
part rather than the histogram filling part.
** Add more word on the single vs all trace explanation **