Sorry if this is kind of a noob question but I'm wondering what the best-performing approach is to the following: I'd like to define several local constants in the body of a function, each of which depends on the value of the previous one(s) in an arbitrarily complicated way. My understanding is that e.g. when doing this with a single constant, the best thing to do is use With
:
f[args___]:= With[{const = (* something *)},
(* body where the value of const may be used many times over *)
]
As I understand it, this is better (per the documentation for With
) than using Block
or Module
more or less because Mathematica does not have to set up a local environment where the value of const may be repeatedly updated throughout the evaluation.
Now, suppose we want to write a function where there will be multiple local constants, each of which depends on the previously defined ones and each of which is used many times throughout evaluation. A very straightforward way to implement this would be to use one Block
where we can mindlessly give names to all our constants and compute them in order, at the expense of forcing Mathematica to waste time pretending that these constants might be updated at some point in the evaluation of the function when in reality they won't. It seems that the solution using With
forces us to use many nested With
statements:
f[args___]:= With[{const1 = (* something *)},
With[{const2 = (* computation using const1 any number of times *)},
...
(* body where the values of all constants may be used many times over *)
...
]
]
Does anyone know whether there is some point (e.g. some number of such nested statements) where the overhead of nesting them like this might become more expensive than just using a flat Block
structure? Or is it always advantageous in these situations to use With
, however many nestings might be required? I would try to test this myself but I'm not confident I understand what's going on well enough to cover the appropriate ranges of test cases and to interpret the results.
With
s might provide a small performance benefit, but they are a maintenance nightmare: Code is much more cumbersome to debug because it has to be heavily refactored before one can be evaluated again step by step. At least for most of my tasks I get way better performance boost byCompile
-ing the most performance critical piece of code. (Btw., I think the C-compiler is way better in exploiting constness than the Mathematica kernel -- even without declaring things as const. Simply because it is given way more time to mull over this.) $\endgroup$LetL
by Leonid Shifrin: mathematica.stackexchange.com/a/10451. $\endgroup$With
supports the (undocumented) syntaxWith[{x=3},{y=x^2},{z=x+y},...]
$\endgroup$