Does it pay to store the value of a struct member in a local variable?

Asked

Viewed 97 times

4

I see several programmers doing this. Instead of accessing a member of a struct directly, it copies the value to a local variable to the function and uses this variable.

Is there performance gain in it? It makes a difference if the structure is in the stack or heap?

If there isn’t, why do it?

1 answer

5


Let’s create a code that makes the two forms of use of the variable, both in stack as in the heap:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
   int i;
} Tipo;

int main() {
    Tipo x = { .i = 10 };
    printf("%d", x.i);
    int y = x.i;
    printf("%d", y);
    Tipo *z = malloc(sizeof(Tipo));
    z->i = 10;
    printf("%d", z->i);
    y = z->i;
    printf("%d", y);
}

Behold the Assembly generated in the Compiler Explorer. Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Access the member on stack generated this Assembly:

mov    eax,DWORD PTR [rbp-0x20]
mov    esi,eax
mov    edi,0x400694
mov    eax,0x0
call   400460 <printf@plt>

And the access to the variable generated this Assembly:

mov    eax,DWORD PTR [rbp-0x4]
mov    esi,eax
mov    edi,0x400694
mov    eax,0x0
call   400460 <printf@plt>

Obviously the address is different, but the code is exactly the same. But to do that second there had to be a copy of the structure value for the local variable, so you had to run more code:

mov    eax,DWORD PTR [rbp-0x20]
mov    DWORD PTR [rbp-0x4],eax

So the performance of using local variable is worse. If you access the local variable several times this additional cost ends up being diluted, but it will always be worse. There are codes that don’t matter. But in C there are cases that make a difference. Extra access to the variable can cost anything from around 1 nanosecond to dozens of nanoseconds, depending on whether you are in the L1 cache or need to access RAM.

Now let’s see in the heap, accessing directly:

mov    rax,QWORD PTR [rbp-0x10]
mov    eax,DWORD PTR [rax]
mov    esi,eax
mov    edi,0x400694
mov    eax,0x0
call   400460 <printf@plt>

And accessing by the local variable:

mov    eax,DWORD PTR [rbp-0x4]
mov    esi,eax
mov    edi,0x400694
mov    eax,0x0
call   400460 <printf@plt>

Here the access to the member of the structure is slightly worse with an extra instruction. If using the variable a few times does not compensate because there is still a code to copy to the local variable, and in this case it is even a little more expensive because of the indirect:

mov    rax,QWORD PTR [rbp-0x10]
mov    eax,DWORD PTR [rax]
mov    DWORD PTR [rbp-0x4],eax

If you use the local variable several times you can compensate yes. The indirect adds an extra cost and the local variable can make it occur only once in the code.

If the gain does not occur in a specific situation I would say that the person copies to the local variable, or because he wanted to better document what he is doing using a significant variable name giving more readability to the code and the performance is not important, or the person does not know that it is potentially worse.

Has language that can behave differently.

  • You win in code readability - the computer has infinite ability to.ler.names.so - but if you just need to read the values of the last attribute, only assim is a name that shortens not only the typing, but the reading of the code. The time to copy the attribute is negligible. Now, in Python for example, yes, access to a local variable assim is faster than self.assim - why the attribute access mechanism is configurable with multiple Hooks, which are avoided with the assignment.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.