gROOT ProcessLineFast

Hi,
I’m trying to use ROOT for dynamic evaluation of C++ code inside a DAQ software; I realized that if I run this code

#include <TROOT.h>

int main(void) {

   for(;;) {
      gROOT->ProcessLineFast("TMath::Pi()");
   }

   return 0;
}

the in-memory process grows at each iteration and memory never freed… but I’m not using any memory allocation mechanism !

I need a way to dynamic evaluate (at runtime) expressions like “vector[0] + matrix[0][2]” inside C++ code…

Can you provide help ?

Thanks in advance,
Gennaro


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.22
Platform: Xubuntu Linux
Compiler: GCC 9.3


Hi Gennaro,
Is the code changing for each invocation?
Cheers, Axel.

Hi Axel,
in the example I attached the code does not change…
in my application code there will be a set (40, 50, …) of expressions to evaluate

Regards,
Gennaro

Hi Gennaro,

Is the set fixed? Are the same expressions evaluated multiple times? What I’m after is: will it help if I explain to you how to get function pointers from the expression, that you then re-use and invoke (at 0 cost) from there on? That’s not useful if each expression is only ever evaluated once.

Axel.

Hi Axel,
yes the set of expressions is fixed and constructed when program starts. Each expression is evaluated for each incoming event. Please explain how to get function pointers in order to re-use them ad each invocation.

Thanks in advance,
Gennaro

Hi Gennaro,

OK perfect! So here’s what you could do:

root [0] gInterpreter->Declare("int Gennaro() { return 42; }");
root [1] auto funcPtr = (int(*)())(gInterpreter->Calc("&Gennaro"))
(int (*)()) Function @0x7f47f3ce5070
root [2] funcPtr()
(int) 42

Invoking funcPtr() is as fast as invoking any other compiled function.

Hi thanks for your support,
your solution works as expected, but there is a problem if the code will be executed again (as example when I stop and start my DAQ) because the functions are redefined and interpreter returns errors…

I solved the problem with gROOT->ProcessLine instead of gInterpreter->Declare but I don’t know if the invocation speed is the same… I also proceed with funcPtr mechanism and it works fine !

Thanks,
Gennaro

Hi Gennaro,

Good! gROOT->ProcessLine() is a bit slower because it includes “user-code protection”, such as if there’s a nullptr dereference, the call won’t crash but an exception is thrown instead. The alternative is to have a counter on the function name and increment that on a re-start of the DAQ.

Cheers, Axel.