mahendiran.b
mahendiran.b

Reputation: 1323

Variable declaration inside loop

I have a function which is doing some operation on array inside loop. After every iteration it is supposed to initialize the array to zero. So which of the following will give a performance benefit?

one.c

int main(void){
 char buf[4096] = { 0};

 while (1 /*flag*/) {

       /*Some operation here*/
    memset (buf, 0, sizeof (buf));
    }
}

two.c

int main(void){

 while (1 /*flag*/) {
       char buf[4096] = { 0};
       /*Some operation here*/
    }
}

In one.c explicit memset is used. But in two.c array is declared inside the loop and initialized to zero.

Upvotes: 3

Views: 367

Answers (3)

Ugh. I see a lot of speculation going on. Let's see:

First of all, ask yourself: does performance even matter? IOW,

  • have you benchmarked your program?
  • did it turn out to be slow because of calling memset or the initialization?
  • did changing it to the other alternative result in significant performance improvement?

I would guess that you haven't benchmarked it yet, in which case you definitely should. Or maybe performance is not really important here, in which case you should go with the stylistically superior one.

In general, however, there are a few things that can be said about this code. Note that this is all speculation, since I don't know what you are doing in the loop and thus can't reproduce your code and benchmark it, but I would.

First of all, I prefer the second version because it minimizes the scope of the buffer. Generally, you want to minimize the lifetime of variables so as to:

  1. minimize the probability of variable name collisions or accidentally re-using variables, and
  2. let the compiler's optimizer re-use their storage for other variables in order to minimize stack usage.

Additionally, today's aggressively-optimizing compilers will most probably treat both pieces of code identically. memset() is usually a compiler intrinsic function, so the compiler knows its semantics (i. e. that it fills memory with bytes). So, the compiler may inline the call to memset() and just emit code that zeroes out the memory if it turns out to be faster to do so, so there's no function call overhead.

The inverse decision can be made too: if the compiler deduces that it's better for some reason (i. e. reduced code size) to call a function, then it can substitute the byte-by-byte zero-initialization of the array to a call of memset(), and often it does indeed.

The argument I've read in some answers/comments that "initializing the array is more costly than resetting memory location" is simply nonsense -- I don't even understand what is meant by "resetting memory location". Both zero-initialization and memcpy(0) do the very same thing in this scenario, and chances are, if you compile with enough optimizations enabled, they will compile to the exact same machine code.

Upvotes: 4

M.M
M.M

Reputation: 141554

These are both exactly the same. In fact both programs could be fully optimized out since none produces any observable behaviour.

If your compiler (at maximum optimization level) does something differently for either program then could report it to your compiler vendor, and also use whichever one seems to be faster based on testing in your environment.

There is no global answer to "what is faster".

Link to example code where I added in some cruft to inhibit optimization - func1 and func2 bodies look pretty similar.

Upvotes: 3

Peixu Zhu
Peixu Zhu

Reputation: 2151

both of them use same size of stack (4KB) to store the buffer, however, in the looping, two.c will not call a function, it directly store 0 to buf, typically use instruction stos, so, if one.c is not optimized enough, two.c seems have better performance.

Upvotes: 2

Related Questions