Do temp variables slow down my program?

8.2k views Asked by At

Suppose I have the following C code:

int i = 5;
int j = 10;
int result = i + j;

If I'm looping over this many times, would it be faster to use int result = 5 + 10? I often create temporary variables to make my code more readable, for example, if the two variables were obtained from some array using some long expression to calculate the indices. Is this bad performance-wise in C? What about other languages?

5

There are 5 answers

9
Shafik Yaghmour On BEST ANSWER

A modern optimizing compiler should optimize those variables away, for example if we use the following example in godbolt with gcc using the -std=c99 -O3 flags (see it live):

#include <stdio.h>

void func()
{
  int i = 5;
  int j = 10;
  int result = i + j;

  printf( "%d\n", result ) ;
}

it will result in the following assembly:

movl    $15, %esi

for the calculation of i + j, this is form of constant propagation.

Note, I added the printf so that we have a side effect, otherwise func would have been optimized away to:

func:
  rep ret

These optimizations are allowed under the as-if rule, which only requires the compiler to emulate the observable behavior of a program. This is covered in the draft C99 standard section 5.1.2.3 Program execution which says:

In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

Also see: Optimizing C++ Code : Constant-Folding

3
R.. GitHub STOP HELPING ICE On

While all sorts of trivial differences to the code can perturb the compiler's behavior in ways that mildly improve or worsen performance, in principle it it should not make any performance difference whether you use temp variables like this as long as the meaning of the program is not changed. A good compiler should generate the same, or comparable, code either way, unless you're intentionally building with optimization off in order to get machine code that's as close as possible to the source (e.g. for debugging purposes).

2
usr On

This is an easy task to optimize for an optimizing compiler. It will delete all variables and replace result with 15.

Constant folding in SSA form is pretty much the most basic optimization there is.

1
steven smith On

The example you gave is easy for a compiler to optimize. Using local variables to cache values pulled out of global structures and arrays can actually speed up execution of your code. If for instance you are fetching something from a complex structure inside a for loop where the compiler can't optimize and you know the value isn't changing, the local variables can save quite a bit of time.

You can use GCC (other compilers too) to generate the intermediate assembly code and see what the compiler is actually doing.

There is discussion of how to turn on the assembly listings here:Using GCC to produce readable assembly?

It can be instructive to examine the generated code and see what a compiler is actually doing.

3
Scott On

You're suffering the same problem I do when I'm trying to learn what a compiler does--you make a trivial program to demonstrate the problem, and examine the assembly output of the compiler, only to realize that the compiler has optimized everything you tried to get it to do away. You may find even a rather complex operation in main() reduced to essentially:

push "%i"
push 42
call printf 
ret

Your original question is not "what happens with int i = 5; int j = 10...?" but "do temporary variables generally incur a run-time penalty?"

The answer is probably not. But you'd have to look at the assembly output for your particular, non-trivial code. If your CPU has a lot of registers, like an ARM, then i and j are very likely to be in registers, just the same as if those registers were storing the return value of a function directly. For example:

int i = func1();
int j = func2();
int result = i + j;

is almost certainly to be exactly the same machine code as:

int result = func1() + func2();

I suggest you use temporary variables if they make the code easier to understand and maintain, and if you're really trying to tighten a loop, you'll be looking into the assembly output anyway to figure out how to finesse as much performance out as possible. But don't sacrifice readability and maintainability for a few nanoseconds, if that's not necessary.