5
$\begingroup$

In general, I think there are two methods of evaluating a variable in Mathematica. My question is about performance of the two methods.

Suppose that our final goal is to evaluate a1.

We know that

a1 is defined by b1,b2,b3
b1 is defined by c1,c2,c3
b2 is defined by c4,c5,c6
b3 is defined by c7,c8,c9
c1 is defined by d11,d12,d13
c2 is defined by d21,d22,d23
...
c9 is defined by d91,d92,d93

If we evaluate a1, then mathematica's evaluating process is

  1. seeks for definition of a1.
    Change the expression of a1 using b1,b2,b3
  2. seeks for definition of b1,b2,b3
    Change the expression of a1 using c1,c2,..,c9.
  3. seeks for definition of c1,c2,..,c9
    change the expression a1 using d11,d12,...,d93
  4. finally evaluate a1

Let's call the above method alpha-method.

But we could use other method, namely beta-method :

  1. Evaluate c1,c2,...,c9,
  2. Evaluate b1,b2,b3
  3. Evaluate a1

The difference of alpha-method and beta-method is that,
for beta-method, there is no work of seeking definitions or changing variables of a expression of a1.
Moreover, we could save some memories like :

  1. Evaluate c1,c2,...,c9, clear d11,d12,...,d93
  2. Evaluate b1,b2,b3, clear c1,c2,..,c9
  3. Evaluate a1.

So I guess that beta-method is faster and more memory-saving then alpha-method.

I saw some elegant solutions for some questions(especially question about function-constructing), which can be classified into alpha-method. Define X using some variables, and define those variables with another variables,... then we see X is completely determined.

A code of alpha-method usually contains just few definitions.

A code of beta-method usually contains many conditionals and loop commands.

Is it true(or worth considering) that beta-method should be used in case the performance is important?

$\endgroup$
3
  • 2
    $\begingroup$ Yes, this is correct. In particular if you want to work with with finite precision numbers, the "beta" method is often more efficient because complicated expressions immediately collapse into a few finite precision numbers which have much less a memory foot print. Moreover, complicated symbolic expressions tend to have many repetitions (think, e.g., of computing the total derivative of the composition of several functions with many variables). $\endgroup$ Feb 20, 2022 at 13:03
  • $\begingroup$ As a side note: Mathematica often branches to more efficient code (that can do the number crunching in hardware) when it detects machine precision inputs. $\endgroup$ Feb 20, 2022 at 13:03
  • $\begingroup$ I suggest following the Wolfram Multicomputation streams on YouTube (here). The Live CEOing Ep 515 gives a good overview of the project and its intent. This topic is ongoing with updates on progress occurring in Live CEOing streams as it becomes available. $\endgroup$
    – Edmund
    Feb 20, 2022 at 14:43

1 Answer 1

6
$\begingroup$

"Alpha" and "Beta" are sometimes respectively called the "lazy" and "strict" evaluation strategies.

If each subexpression is used unconditionally exactly once in the overall computation, then both strategies have essentially the same time efficiency. But the lazy strategy will use less peak working memory as it will discard intermediate results after they have been used.

If some subexpressions are used multiple times, then the lazy strategy will incur extra time to recompute those subexpressions. But it retains its peak memory advantage.

On the other hand if some subexpressions are used only conditionally, then the lazy strategy will run faster since it need not compute unused subexpressions at all. Again, it retains its peak memory advantage and may in fact use less memory due to the skipped computations.

In summary, the lazy strategy is generally more space efficient than the strict strategy but may be faster or slower depending upon the structure of the problem space. We usually end up using a hybrid strategy. Much of the fun and grief in programming comes from finding the right mix.

$\endgroup$
2
  • $\begingroup$ But frequently lazy is combined with memoizing, no? Which makes the time nearly as efficient as strict, assuming memoizing is fast (e.g., amortized O(1)). $\endgroup$
    – davidbak
    Feb 21, 2022 at 1:33
  • 1
    $\begingroup$ @davidbak Agreed, that is a common hybrid strategy which trades space and code-complexity for time. The space part is obvious but we often overlook the code-complexity part... the old saw: "cache ⊃ bug". For example, the common idiom m:f[...] := m = ... looks simple but can generate memory leaks if used indiscriminately. Cached laziness is great, but like all sharp tools it must be handled carefully. (Haskell embraces implicit cached laziness in a big way... and Simon Peyton-Jones once opined that the resulting opaque performance model presents a major barrier of entry for new users.) $\endgroup$
    – WReach
    Feb 21, 2022 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.