Performance Problem using TRefArray

Dear ROOT support!

I have a performance problem using TRefArray. I boiled my use case down to the following program:

#include <iostream>
#include "TTree.h"
#include "TFile.h"
#include "TStopwatch.h"
#include "TRefArray.h"

int main() {

  TFile file("test.root","RECREATE");
  TTree tree("tree","tree");

  TObject* pObject = 0;
  TRefArray* refArray = 0;

  tree.Branch("pbranch",&pObject);
  tree.Branch("refArray",&refArray);

  TStopwatch s;

  for(unsigned int i=0; i != 100000; ++i) {

    Int_t ObjectNumber = TProcessID::GetObjectCount();

    pObject = new TObject;
    refArray->Add(pObject);

    tree.Fill();

    if(i % 1000 == 0) {

      s.Stop(); s.Print("u"); s.Start();

    }

   TProcessID::SetObjectCount(ObjectNumber);

  }

  file.Write();

}

Using version 5.24/00b.

$ g++ write.cc -o write `root-config --cflags --libs`
$ ./write
Real time 0:00:00.000203, CP time 0.000
Real time 0:00:00.024572, CP time 0.020
Real time 0:00:00.063081, CP time 0.070
Real time 0:00:00.103676, CP time 0.100
Real time 0:00:00.145511, CP time 0.150
Real time 0:00:00.207732, CP time 0.200
Real time 0:00:00.230565, CP time 0.230
Real time 0:00:00.260324, CP time 0.270
Real time 0:00:00.289173, CP time 0.290
Real time 0:00:00.264958, CP time 0.260

You see that it gets slower and slower though there is no memory leak.

I’ve read the Users Guide about TRef and I’m quite sure that I should reset the ObjectCount like it is done in the Event example. However I couldn’t figure out the right way to do it.

What I want to achieve is that I keep track of instances of a class which are used in another branch so that I can safely delete them all in one place at the end of my “read” loop in another program.

Thanks in advance,

Sebastian

[quote] However I couldn’t figure out the right way to do it.[/quote]A priori you would need to call it at end of your loop. You also should ‘Clear’ the refArray. (refArray->Clear() );

Cheers,
Philippe.

[quote=“pcanal”][quote] However I couldn’t figure out the right way to do it.[/quote]A priori you would need to call it at end of your loop. You also should ‘Clear’ the refArray. (refArray->Clear() );
[/quote]

Dear Philippe!

Thanks for your answers. Obviously the Clear() was missing in my example problem. In my real program setting the ObjectCount at the end of my loop cured the slowing down.

Concerning the TRefArray. I want to delete the objects that are referenced. I do it via a loop and the At() function. Should the Delete() and Clear() (if SetOwner is set) of TRefArray work as well?

Thanks,

Sebastian

[quote]Should the Delete() and Clear() (if SetOwner is set) of TRefArray work as well?[/quote]The TRefArray::Delete’s documentation is a bit misleading. The TRefArray can never ‘own’ the object it points. The difference between TRefArray::Clear and TRefArray::Delete is that the Delete also deletes one internal array (rather than just reseting it to zero). A priori you only need to use Clear.

Cheers,
Philippe.