Contrib equationReader/Efficiency

From OpenFOAMWiki

How fast is equationReader?

The bottom line is: I don't know yet, but am planning on testing it soon. Once the test is done, I'll put the results (bad or good) here. I believe that equationReader will prove to be a little slower than a hard-coded solution, but not too slow to offset the benefits gained in flexibility.

1 Parsing and evaluating

There is a difference between parsing and evaluating. When the equation is first read, it is a human-readable string expression. equationReader translates the human-readable form into an operation list. This is parsing. To calculate the result, equationReader does a forAll(operations, i). This is evaluating.

Parsing happens only once, and is slow. Evaluating happens at every cell index, at every timestep (or however you've used it), and it is fast.

2 Burn all conditionals

Conditionals are slow. In the framework of equationReader, one if or switch slows a single equation operation by about 25%. A word comparison - that slows things by over 1600%.

equationReader has a design philosophy: put no conditionals in the way of an evaluate function. To achieve this I implemented a function-pointer framework.

3 Function-pointers

Apparently in C++ you can have pointers to functions. The syntax looks a little odd:

       void (Foam::equationReader::*reportScalarOperationFunction_)
       (
           const label&,
           const label&
       ) const;

That's not a function - it's a pointer. You don't see these too often because C++'s virtual functions do the same thing - only you need a hierarchy of derived classes. In theory, virtual functions have slightly more overhead than function-pointers because each virtual function call requires a hash-table look-up, unlike the direct use of function-pointers.

Anyway, these function pointers can all be assigned during parsing, and called directly during evaluation. Essentially this moves all conditionals into the parser, and their result is permanently remembered. In short: these make equationReader faster.

Now, there's not a single conditional encountered during an evaluate function call. Even all the debug switches have been converted to function-pointers.

4 Function objects

Apparently function-pointers are old-school, and the next best thing are function-objects, or "functors". Function-objects are better because they can be inlined, unlike function-pointers. Well, I didn't get the memo until it was too late for this version. Maybe in another version.