I'm wondering if in C/C++ it is better to declare a new array on each round of loops:
while(true) {
char array[255] = "";
// Hacer algo con el array ...
}
Or empty it at each turn of it:
char array[255] = "";
while(true) {
for(short i = 0; i < sizeof(array); i++) {
array[i] = 0;
}
// Hacer algo con el array...
}
By best I mean both from a performance (speed) and best practices perspective.
As far as best practice goes, it's best to declare the variable in the smallest/narrowest scope you can (in this case inside the loop if it's not going to be used outside anywhere). It makes the code easier to maintain (eg: you don't have to go up 100 lines to see what type the variable x is initialized with) and in some cases the compiler might apply some optimization method.
Now from a performance point of view, it's going to depend a lot on the compiler (and language) you're using and you'd have to test which one is better. Modern compilers take care of optimizing the generated code , so the result should be very similar (if not the same) in both cases.
...That was the theory, now let's see the practice. I have created three test cases (although perhaps not in the most scientific way) with loops that repeat 10 million times and have run them 20 times to see the results. This is the code:
Case 1: statement inside the loop
Case 2: Declaration outside the loop, emptying with for loop
Case 3: Declaration outside the loop, flush with memset
And the results were (drum roll):
Which is a bit ******** because it destroys
allpart of the theory that I put above. For the first and third cases, it would be true, but not for the second case (surely I did something wrong... or I have the worst compiler in the world, which is also quite possible).I assume that the complexity will be linear and the memory reservation and initialization process will be just as expensive or with similar costs for each round of the loop; but it is difficult to evaluate since the compiler can make decisions to optimize the code.
It seems that you are facing a case of early optimization :
If you consider that part of the code to be critical, my advice is to try different compiler optimization options using one option and the other, we will never outsmart the compiler... even code that we may have inefficiently written by the compiler you can translate it into something higher performance behind the scenes. I bet even in the worst case your 255 element array won't be a performance bottleneck for your program and the compiler will do a good job of optimizing your code.
Edited:
On the other hand, depending on your intended use of
array
, you can skip the initialization step:If you don't assign a value to the array, it won't be initialized to 0 and therefore, it will be one less process to do in each round of the loop (don't pay for what you don't use, this is a C++ principle). This will be useful if the first thing you do with
array
is write to it, so its previous information isn't relevant... it might even be a reason for the compiler to reuse the space ofarray
on each loop instead of creating it anew.Good practice indicates that it is recommended that the scope of the variables be as small as possible. This recommendation is intended to prevent the reuse of variables for different purposes.
In terms of performance it seems obvious to deduce that forcing the program to allocate and initialize X bytes of memory on each iteration of a loop is going to be more expensive than allocating once and initializing on each iteration of the loop.
However, performance is often a controversial topic. In the example you propose, can the time the system will spend reserving 255 bytes in each array be considered important? The final answer depends on the requirements of the algorithm. If, for example, this function is going to take half a second and is only executed when the user presses a button, it can be safely considered that the time is negligible... if instead the time is a critical unit and the rest of the algorithm is super optimized things change.
My recommendation is that you first worry about creating readable code and, once finished, check if it is necessary to optimize it or if it meets the specifications with what it has.
By the way, to initialize memory you can make use of
memset
instead of creating your own loop.Note that creating an array local to the function is trivial for compilers in most cases, since it is a simple stack size adjustment.
On many architectures, adjusting the stack size occupies very few machine code instructions, and does not access memory . The simple act of 'cleaning' an array with
array[0] = 0
can involve that dreaded memory access (it depends on the use of the array inside the loop, so that the last accesses cause `array[0]' to be inside the processor cache lines ).The curious value obtained when clearing the array using
memset()
is possibly due to the compiler. gcc , for example, implements via inlinememset()
generated machine code , without making any actual function calls at all. This, along with its own optimizations, will be responsible for such unexpected speed.Comparing it with the case of
array[0]=0
, here we do force the compiler to generate code; No matter how much they are optimized, compilers still don't know how to program on their own ;-)I admit that the speed when using
memset()
it surprised me.