Hello Rene, I understand. G__CallFunc is too cumbersome. In that case, I recommend using template function and predicate. This technique is used in STL generic algorithm. The concept Renard wants to achieve is similar to that of generic algorithm. This will provide a reasonable solution. Please examine following code. If you want to know more about this technique, please refer to books about STL. Good things about this solution are - cint can bytecode most of the execution. - flexibility for adding arguments to predicate object - used in STL C++ standard library. So the concept is standard Drawback is - You need to learn concept of template and generic algorithm which is a little complex. Thank you Masaharu Goto // A frame method template<class Action> void frameMethod(Action& f,int n) { for(int i=0;i<n;i++) { f(i); } } // a class with operator() to be used as predicate of the frameMethod // This first example is the simplest one. You just have operator() class Print { public: void operator()(int a) { printf("print %d\n",a); } }; // a class with operator() to be used as predicate of the frameMethod // Second example, you can give an argument. This will give you extra // flexibility class Add { int c; // argument buffer public: Add(int x=0) { c=x; } // initialization of the argument void operator()(int a) { printf("add %d\n",a+c); } }; // main routine int main() { for(int i=0;i<2;i++) { frameMethod(Print(),2); //give Print object as a predicate } for(int i=0;i<2;i++) { frameMethod(Add(1),2); //give Add object with an argument as predicate } } > >Hi Masa, >The solution via G__CallFunc is OK for system developpers, but not >for the end user. It would be good if you could find a solution to this >problem. > >Rene > > >Masaharu Goto wrote: >> >> Hello Renard, >> >> The reason of pointer to function being slow in the interpreter >> is because Cint handles pointer to interpreted function and >> compiled functions in the same context. When Cint gets pointer >> to function, it searches through both interpreted and compiled >> function table. And bytecode compilation is voided. So, speed >> penalty is 2 fold, for not using bytecode and searching function >> table. >> >> I understand what you want to do. For this purpose there is >> G__CallFunc utility class. This class must be used in an compiled >> code, so you need to precompile readPreanRootSkeleton(). G__CallFunc >> is documented in $CINTSYSDIR/doc/ref.txt >> >> Thank you >> Masaharu Goto >> >> >Date: Tue, 12 Dec 2000 16:32:35 +0100 >> >From: "F. Renard" <frenard@cea.fr> >> >To: rootdev@pcroot.cern.ch >> >Subject: loop function >> > >> >Hello Root team, >> >intro : i want to loop on events in a root ntuple to produce histos in >> >an interactive way >> >(with macros in a interactive root session). I used the example and >> >evrything works fine. >> >But i don't want to copy-paste the common part of initializing and >> >looping over events >> >in every new macro. So i tried (and succeed) to make a common fonction >> >which calls a user function >> > >> >It looks like this : >> >/************************************************************************/ >> > >> >void readPreanRootSkeleton(TTree *t1, void (*userFunc)(), int nEvent) >> >/************************************************************************/ >> > >> >{ >> > Int_t nevent = t1->GetEntries(); >> > cout<<"Il y a "<<nevent<<" evenements"<<endl; >> > Int_t nbb = 0; >> > if (userFunc == 0) { cout << "!! userFunc=0 !! Rien a >> >faire"<<endl;} >> > >> > if (nEvent > 0) { nevent = nevent > nEvent ? nEvent : nevent;} >> > cout<<"Je traite "<<nevent<<" evenements" << endl ; >> > >> > for (Int_t i=0;i<nevent;i++) >> > { >> > nbb += t1->GetEvent(i); //read complete event in memory >> > >> > (*userFunc)(); >> > } >> >} >> > >> >This part is located in a macro file common to every user macros >> > >> >Then i can write a simple macro : >> >int macro() >> >{ >> > // do initialization >> > // ....... >> > >> > // event loop >> > readPreanRootSkeleton(tree, &(myFunc), 0); >> >} >> > >> >void myFunc() >> >{ >> > // operations on event to fill histograms... >> >} >> > >> >I find this an elegant way because the loop function >> >readPreanRootSkeleton(...) is >> >common to every user of the ntuple, and this allow writing macros in a >> >very light way. >> >The most important point is to use a pointer to a function which allows >> >for flexibility. >> > >> >First Question >> >Why is this so slow ? I compared with the same macros, changing only the >> >pointer function call >> >ォ (*userFunc)(); サ >> >to the real name >> >myFunc(); >> >and the time spent was largely reduced >> >I wasn't expecting this because in principle the only difference is the >> >need for dereferencing >> >the pointer >> >Can you help me improving this loop function performances ? >> > >> >Second Question >> >I tried then to first make a shared library from the common parts >> >ォreadPreanRootSkeleton()サ >> >I used your example to generate the dictionnary... and everything works >> >fine. >> >But when i call the function in root, with a pointer to myFunc() which >> >is still loaded from a macro, i get : >> > >> >Limitation: Precompiled function can not get pointer to interpreted >> >function as argument FILE:ana1212.cxx LINE:67 >> > >> >So i cannot use this loop function in a shared library loaded in root. I >> >am surprised because other functions in ROOT >> >are allowed to use pointers to interactively defined functions. For >> >example : >> >http://root.cern.ch/root/htmldoc/TFitter.html#TFitter:SetFCN >> >which as a prototype >> > void SetFCN(void *fcn) >> > >> >Is there a way to have root accept these king of argument in my function >> >? >> > >> >Thank you >> > >> >FRenard >> > >> >PS: >> >if you need extra info or listings, please ask me >> >
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:39 MET