Difference between revisions of "Contrib equationReader/Efficiency"
(Created page with "''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. ...") |
|||
Line 22: | Line 22: | ||
) const; | ) 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 | + | 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. | 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. |
Revision as of 15:36, 15 September 2011
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.