Reputation: 9173
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
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
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
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
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