1

I think non-static var in loop could make some overhead (construct / destruct for each loop). Am I right? then why we don't use static var in main-loop?

for(;;){
  type1 var1;
  type2 var2;
//(var1, var2 construct here )

....
   // Do something
....
  
//(var1, var2 destruct here )
}
for(;;){
  static type1 var1;
  static type2 var2;

//(var1, var2 don't construct here )
....
   // Do something
....
  
//(var1, var2 don't destruct here )
}
sunkue
  • 278
  • 1
  • 9
  • 5
    Such micro-optimizations would almost always be a waste of effort on your side. It's a premature optimization. If you really need to optimize your program (because it doesn't meet some actual requirements), then create a release build with compiler optimizations enabled, and measure and profile to find the actual bottleneck of your program, and only optimize the top one or two of them. – Some programmer dude Sep 23 '21 at 14:02
  • 6
    `static` will change the behavior of the function. Additionally, `static` local objects need to guarantee thread-safe initialization so it is likely worse for performance. And depending on what `type1` and `type2` are the construction/destruction may not be expensive. If they are `int` it is basically free. There is no associated memory allocation and no initialization. – François Andrieux Sep 23 '21 at 14:02
  • Shouldn't you reinit `var1`/`var2` anyway in place of the construct? And moving the type outside of the loop seems simpler too. – Jarod42 Sep 23 '21 at 14:03
  • 1
    Your solution will not work in a recursive function, as every instance of the function will require its own copy of its local variables. – Andreas Wenzel Sep 23 '21 at 14:05
  • 3
    If you're worried about cost of construction/destruction then you can just put the variables outside the loop. But then you'd need to make sure they're iniitialized correctly on each iteration - so don't do this unless profiling indicated that it's needed. – interjay Sep 23 '21 at 14:09
  • ... and if initialization at the start of every iteration involves destroying the previous state, you may be gaining nothing at all. So to re-iterate, always profile first. – StoryTeller - Unslander Monica Sep 23 '21 at 14:19
  • @interjay We use this "trick" frequently with _vectors_ that are "logically private" only to each iteration (in HPC apps). Moving it outside and clearing it at the beginning of each iteration reduces a lot of dynamic memory allocations, which sometimes speedups the computation significantly. The drawback is just less readable code. However, sometimes we need the same at the level of multiple function calls (instead of loop iterations). Then, `static` or `thread_local` can be useful. – Daniel Langr Sep 23 '21 at 14:20

1 Answers1

2

Your second snippet is not thread safe. These days, you always need to consider thread safety as computational gains have moved from faster clock speeds to more processor cores.

You can trust a compiler to optimise out the first snippet. If you're ever in doubt, check the generated assembly.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Why should the second snippet not be thread-safe? [Is local static variable initialization thread-safe in C++11?](https://stackoverflow.com/q/8102125/12149471) – Andreas Wenzel Sep 23 '21 at 14:12
  • 1
    @AndreasWenzel - Okay, you initialized them. Now execute the loop from different threads. Read, write to the variable... etc etc – StoryTeller - Unslander Monica Sep 23 '21 at 14:12
  • 1
    @AndreasWenzel The function can't be run concurrently on multiple threads because they would share a non-synchronized state. It is not thread safe because it can't be called by multiple threads at the same time. – François Andrieux Sep 23 '21 at 14:15
  • @StoryTeller: Ah, yes, you are right. However, that problem is not specific to multi-threading, as the same problem also exists in single threads, if a second instance of the function is called while the first instance is still running (for example if the function is recursive). But you are right that the term "thread-safe" is still appropriate. [Reentrancy](https://en.wikipedia.org/wiki/Reentrancy_(computing)) and [Thread-Safety](https://en.wikipedia.org/wiki/Thread_safety) are closely related. – Andreas Wenzel Sep 23 '21 at 14:27
  • @FrançoisAndrieux: Ah, yes, I didn't take the race condition when writing into account. That issue is indeed specific to thread-safety and does not occur with a single-threaded function (although it is still relevant for single-threaded reentrancy, for example in the context of an asynchronous signal handler). – Andreas Wenzel Sep 23 '21 at 14:44