Moses
Moses

Reputation: 9173

Reducing for loop overhead

I have a need to iterate through an amortization formula, which looks like this:

R = ( L * (r / m) ) / ( 1 - pow( (1 + (r / m)), (-1 * m * t ) );

I'm using a for loop for iteration, and incrementing the L (loan value) by 1 each time. The loop works just fine, but it did make me wonder about something else, which is the value (or lack thereof) in performing basic operations before a loop executes and then referencing those values through a variable. For example, I could further modify this function to look like

// outside for loop
amortization = (r/m)/(1 - pow( (1+(r/m)), (-1*m*t) ) )

// inside for loop
R = L * amortization

This way, instead of having to perform lots of math operations on every iteration of the loop, I can just reference the variable amount and perform a single operation.

What I'm wondering is how relevant is this? Is there any actual value in extracting these operations, or is the time saved so small that we're talking about a savings of milliseconds from a for loop that iterates approx. 200,000 times. Follow up question: would extracting operations like this be worth it if I were doing more expensive operations like sqrt?

(note: in case it matters, I'm asking about this specifically with c++ in mind)

Upvotes: 1

Views: 1089

Answers (4)

Xion
Xion

Reputation: 22770

Compilers would exercise an optimization technique here which is called loop invariant code motion. It does pretty much what you did manually, i.e. extracting a constant part of expression evaluated repeteadly in loop into a precomputed value stored in variable (or register). Hence it is not likely that you gain any performance by doing this yourself.

Of course if it's critical speed-wise, you should profile and/or review the assembly code produced by compiler in both cases.

Upvotes: 2

Nemo
Nemo

Reputation: 71525

As others have mentioned, good compilers will do this sort of optimization automatically. However...

First, pow is probably a library function, so your compiler might or might not know it is a "pure" function (i.e., that its behavior depends only on its arguments). If not, it will be unable to perform this optimization, because for all it knows pow might print a message or something.

Second, I think factoring this expression out of the loop makes the code easier to understand, anyway. The human reading your code can also factor out this expression "automatically", but why make them? It just distracts them from your algorithm's flow.

So I would say to make this change regardless.

That said, if you really care about performance, get a decent profiler and do not worry about micro-optimizations until it tells you to. Your priorities early on should be (a) use a decent algorithm and (b) implement it clearly. And not in that order.

Upvotes: 2

Peter Alexander
Peter Alexander

Reputation: 54270

Compilers already move loop invariant code to the outside of the loop. This optimisation is known as "Loop Invariant Code Motion" or "Hoisting Invariants".

If you want to know how much it affects performance then the only way you are going to know is if you try. I would imagine that if you are doing this 200,000 times then it certainly could affect performance (if the compiler doesn't already do it for you).

Upvotes: 2

jcoder
jcoder

Reputation: 30035

When you have opimizations turned on then moving constant expressions outside of a loop is something that compilers are pretty good at doing on their own, so this might buy you no speed up anyway.

But if it doesn't this looks like a reasonable thing to try, and then time it IF this is actually taking longer than you require.

Upvotes: 1

Related Questions