|
|
(One intermediate revision by the same user not shown) |
Line 1: |
Line 1: |
− | ''How fast is '''equationReader'''?'' | + | This project has migrated over to '''github'''. |
| | | |
− | '''equationReader''' takes between 10 to 20 times longer than a hard-coded solution. This is because it is currently interpretive. I thought the fancy ''function-pointer'' framework I used would be faster, but it isn't. Don't despair, the next version will actually ''compile'' your equations on the fly... in theory this will make it equal that of a hard-coded solution. | + | '''''[http://github.com/Marupio/equationReader/wiki Click here for the new website.]''''' |
| | | |
− | == Efficiency discussion ==
| + | http://github.com/Marupio/equationReader/wiki |
− | | + | |
− | === 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 <tt>forAll(operations, i)</tt>. 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.
| + | |
− | | + | |
− | === Burn all conditionals ===
| + | |
− | Conditionals are slow. In the framework of '''equationReader''', one <tt>if</tt> or <tt>switch</tt> 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 <tt>evaluate</tt> function. To achieve this I implemented a ''function-pointer'' framework.
| + | |
− | | + | |
− | === 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 <tt>debug</tt> switches have been converted to ''function-pointers''.
| + | |
− | | + | |
− | === 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.
| + | |