Reputation: 1323
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
Reputation: 9343
Ugh. I see a lot of speculation going on. Let's see:
First of all, ask yourself: does performance even matter? IOW,
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:
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
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
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