Whether compilers equally optimize work with local and static variables.

For example, two sample code:

int c=0; for (int i=0;i<100;++i) {...;++c;} 

.

 for (int i=0;i<100;++i) {...;static int c;++c;} 

Are there any differences in the speed of their implementation?

  • one
    There is a suspicion that the compiler will throw out both of these unnecessary cycles ... - Vladimir Martyanov
  • @ Vladimir Martiyanov In what sense will "throw out"? - Nokolay1979
  • one
    In direct. There will be no cycle, and 100 will be written to c at once. It may not even be a variable c. The compiler will see that the cycle can be thrown out and thrown out. And if c is not used anywhere else - and her too. - Vladimir Martyanov
  • one
    It’s not at all obvious that there is something else there, especially when it comes to "optimizing" the increment. You can compile both options and see what code is obtained and, based on this, choose the most optimal (in terms of speed or size) option. - Vladimir Martyanov
  • 2
    @ Nokolay1979 If c and i go the same way, then the compiler can easily throw out one of these variables. Yesterday I just reviewed the compilation page here, there was constantly going to the array arr [j + g], and j grew monotonously. The optimizer just threw out the variable g and led in the register altogether j + g - Mike

2 answers 2

In principle, compilers may act in such cases at their discretion, within certain limits. Static variables are not used in programs just as they can be reused and theoretically in different parts of the code. Your loop can pass a pointer to a static variable to some called function and through this pointer it can be accessed even after the loop ends. In this regard, the optimizer is very careful with operations with it.

According to the results of the tests, the GCC optimizer in the first case:

 int c=0; for (int i=0;i<100;++i) {...;++c;} 

I did not allocate memory for variables i and c , but used 1 processor register to maintain one value, i.e. he realized that the values ​​of the variables at all iterations coincide and just threw out one of them.

In the second case:

 for (int i=0;i<100;++i) {...;static int c;++c;} 

the compiler allocated for the variable c memory in the data segment (and not the stack, as with the usual internal variables of functions). For the convenience of organizing transitions, the variable i began to lead in the reverse order (from 100 to 0), since the value of the variable i itself is only needed for counting the cycle and is not used anywhere else. Static variable c optimizer at each iteration of the cycle gets out of RAM, adds 1 and puts back into RAM. That in terms of code efficiency is clearly a slow operation.

Another thing to add is that if a static variable lies in a data segment, it differs from the global one only by its scope. In this regard, the use of such variables in a multithreaded application will create a lot of problems and will require taking locks before working with it.

Based on this, we can conclude that static variables should be used when they are really needed to implement a specific algorithm.

  • Thanks again - Nokolay1979
  • @Mike >> Your loop can pass a pointer to a static variable to some called function, and through this pointer it can be accessed even after the loop ends. For such a brilliant technical solution is to give a premium. In the form of a sentence to write "on its own" - gbg
  • @gbg And what you do not like about this solution is a static variable in the data area, it lies there all the time. If the function and cycle are run a second time, they will work with that old variable that did not even change the value between calls. And if you want to change the value - then please change to health. True, in that case, it would have been easier to declare global, it wouldn’t change the essence of its storage at all, although it would have looked more logical than “following a pointer” :) - Mike
  • @Mike, have you seen a project in which hundreds of modules and millions of lines of code? So, the appearance of global entities in such a project, such as static variables and global variables, slows down debugging and making changes hundreds of times. The reason is that the edit is not made by the developer, who kneaded these noodles, but the kneader has already been fired. As a result, the ruling party must first examine all the subtleties (aha, the entire state diagram of the global entity), and only then correct it. Otherwise, glucodrome. So singletons and other globalism - in the bath. With them neither testing nor refactoring go smoothly. - gbg
  • one
    @gbg The question in question was about the speed of work and, in general, the physical organization, in the answer I emphasized the global nature of this variable, having just indicated that it is always possible to work with it. Questions to maintain such a code no one put. Or, instead of answering a specific question, do you suggest answering “don't do this never” - Mike

First, these two code fragments are not equivalent.

In this code snippet

 int c=0; for (int i=0;i<100;++i) ++c; 

variable c has an outer declaration area with respect to the loop.

In the same code snippet

 for (int i=0;i<100;++i) {static int c;++c;} 

variable c has an declaration area corresponding to the composite loop clause.

Therefore, semantically, these are two different code fragments.

Declaring a scalar variable as static inside a compound sentence of a loop only makes sense if the program’s control passes through this loop several times and you need to calculate some total value for all activations of the loop inside the loop.

But at the same time there is a problem that outside the loop this variable is not visible. Therefore, it is difficult to find some meaningful application of this approach.

Unless somewhere in recursive functions you can find such trick application.

Talking about some kind of optimization sucked out of a finger and comparing these two code fragments according to a single criterion is generally meaningless.

  • one
    By the way, I don’t like static at all. where is its initial value? the compiler is not required to reset the variables itself. But write the most = 0 the same kind of thing as it should be - Mike
  • I added ..., i.e. c we can use in the body itself for - Nokolay1979
  • one
    @ Nokolay1979 No, this is not the case, because in the first code fragment this variable is reset to zero each time before the loop. - Vlad from Moscow
  • one
    @ Nokolay1979 The question is completely meaningless. - Vlad from Moscow
  • one
    @ Nokolay1979 In your cycles, all that is done with the variable c is that it is incremented. Therefore, it does not matter at all how the static variable is declared or not. The only difference is that in the latter case the final value must be stored in static memory. But it has absolutely no effect on some contrived optimization. - Vlad from Moscow