I’m generating automatic C++ code from python, in particular I need to select some events for a list of events. I declare some selections:
selectionA = Selection(name="selectionA", formula="A>10")
selectionB = Selection(name="selectionB", formula="cobject->f()>50")
selectionC = selectionA * selectionB # * means AND
this generate the C++ code:
for(...) { // cicle on events
event = GetEvent(i);
bool selectionA = A>10;
bool selectionB = cobject->f()>50;
bool selectionC = (A>10) and (cobject->f()>50);
if (selectionA) { histo_selectionA->Fill(event); }
if (selectionB) { histo_selectionB->Fill(event); }
if (selectionC) { histo_selectionC->Fill(event); }
}
This is not very smart, because the smartest code will be:
bool selectionC = selectionA and selectionB
This problem seems to be simple, but it is not, because I have 100+ base selections (as selectionA or selectionB) and 300+ derived selections, and of course a derived selection can be derived from derived selection. Obvious derived selections are not derived from base selections using a regular pattern.
I understand that it is diffult to answer, but can someone give me some hints? For example: is it really necessary to write smart code? I mean, compilers are not able to optimize this code?
It’s unlikely that a compiler could optimize this code. Partly because
cobject->f()might have side effects the compiler can’t see.You could help in a minor way by declaring your bools as
const.Otherwise, it looks like you’re already overloading operators to compose selections. So it shouldn’t be too hard to make a composed selection use the names of the selections its composed from instead of the expressions. This does some optimization for you and will allow the compiler to optimize further if possible, especially if you declare your selection bools as
const.You will also have to be careful to emit the code to initialize the
boolflags in the same order the selection objects are created in Python. This will make sure aboolis always declared and initialized before its used later. You can do this by having a list in the PythonSelectionclass and have the__init__method add the newSelectionto that list. Of course, if you createSelectionobjects that you then throw away that might be a problem. But if you keep them all, it works.