This, from Computational Mathematics by B. P. Demidovich and I. A. Maron:

To illustrate the compilation of a computational scheme, suppose
it is required to compute the values of the analytically specified
function

y= f(x)

for certain values of the argument: x = x_1 , x_2 , \cdots , x_n . If the number of these values is great, it ‘is not advisable to compute them separately, first f(x_1) , then f(x_2) , and so on, each time performing the whole sequence of operations indicated by the symbol f . It is much better to separate f into elementary operations

f(x) = f_m ( \cdots (f_2 (f_1 (x))) \cdots)

and carry out the computations as repeated operations:

u_i (x_i) = f_1(x_i)\,(i=1,2,\ldots,n),
v_i (u_i) = f_2(u_i)\,(i=1,2,\ldots,n),
\cdots \cdots \cdots
f_m (w_i)  \,(i=1,2,\ldots,n),

performing one and the same operation f_j\,(i = 1, 2,\ldots, m) for all values of the argument under consideration.

Although this comes from the era of hand calculations, it’s good advice for programming as well. It’s always better to break down the problem into smaller portions and work your way through. Not only is the code easier to debug but frequently it decreases the computational cost.