In my experience, the rule of thumb is that the generated code will be efficient if the code inside Compile
more or less resembles the code I would write in plain C (and it is clear why). Idiomatic (high-level) Mathematica code tends to be immutable. At the same time, Compile
can handle a number of higher-level functions, such as Transpose
, Partition
, Map
, MapThread
, etc. So, if you write your code in this style and hand it to Compile
, you have to keep in mind that lots of small (or large) memory allocations on the heap, and copying of lists (tensors) will be happening. Since this is not apparent for someone who is used to high-level Mathematica programming, the slowdown this may incur may be surprising. Things to watch for in the printout of CompilePrint
function:
- Calls to
CopyTensor
- Calls to MainEvaluate (callbacks to Mathematica, meaning that something could not be compiled down to C)
So, in summary - if you want your code to be as fast as possible, think about "critical" places and write those in "low-level" style (loops, assignments, etc) - the more it will resemble C the more chances you have for a speed-up. You will have to go against Mathematica ideology and use a lot of in-place modifications. Then your code can be just as fast as hand-written one. Usually, there are just a few places in the program where this matters (inner loops, etc) - in the rest of it you can use higher-level functions as well.