0

I wonder in C, in the case a function is called a huge amount of times, if a static array is faster to deal with than a non-static array.

First case: Non-static int array of 10 int:

void useNonStaticIntArray(int i){
    int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    array[i] = i;
}

int main(void){
    int i;
    for (i = 0; i < 1000000000; i++) {
        useNonStaticIntArray(i % 10);
    }
    return 0;
}

Second case: static int array of 10 int:

void useStaticIntArray(int i){
    static int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    array[i] = i;
}

int main(void){
    int i;
    for (i = 0; i < 1000000000; i++) {
        useStaticIntArray(i % 10);
    }
    return 0;
}

Third case: Non-static int

void nonStaticInt(int i){
    int a;
    a = i;
}


int main(void){
    int i;
    for (i = 0; i < 1000000000; i++) {
        nonStaticInt(i % 10);
    }
    return 0;
}

Fourth case: static int

void staticInt(int i){
    int a;
    a = i;
}


int main(void){
    int i;
    for (i = 0; i < 1000000000; i++) {
        staticInt(i % 10);
    }
    return 0;
}

So I've done some testing on a Debian virtual box:

1)

time ./a.out 

real    0m7.733s
user    0m7.696s
sys 0m0.008s

2):

time ./a.out 

real    0m5.477s
user    0m5.416s
sys 0m0.008s

3)

time ./a.out 

real    0m5.764s
user    0m5.736s
sys 0m0.000s

4)

time ./a.out 

real    0m7.189s
user    0m7.016s
sys 0m0.032s

So it looks like the static is faster than the non-static, I tested several times to be sure and it seems to always (for the 10 times I tested) be the case.

Now I have 3 questions: - Have I done something wrong that falsify the results ? (They were what I expected) - Is it always the case no matter the size of the array ? (from 1 to N, N -> max stack possible value) - How does it really work ?

5
  • 5
    The static array will be initialised once. The non-static array will be initialised every time the function is called. When timing, make sure you turn optimisations off (or use the result) to ensure the function is called. Commented Jan 1, 2020 at 14:23
  • 1
    How does it really work ? - inspect the assembly generated by the compiler. Commented Jan 1, 2020 at 14:25
  • 3
    Is this plain curiosity? Or is there some other problem you need to solve? Micro-optimizations like these are often not very useful, and by adding static you change the semantics of the array quite considerably. And if it's not curiosity have you measured in your real program that this is a top-three bottleneck of your program? And did you build with optimization enabled before measuring (in your real program, since the code you show will be optimized to empty programs)? Commented Jan 1, 2020 at 14:27
  • It is only for curiosity meaning, thanks for the explanations. Commented Jan 1, 2020 at 14:31
  • The function definitions of nonStaticInt and staticInt are exactly the same in the third and fourth case. Commented Jan 1, 2020 at 21:34

1 Answer 1

2

Your test is not really measuring anything.

An optimizing compiler is smart enough to understand that the code does nothing; for example gcc compiles both the static and non-static version to an empty function (i.e. the code is the same as {}).

See https://godbolt.org/z/9r8Hxi .

Note also that there is a difference in semantic (there will be just one instance of the static array, reused between calls and instead the non-static array is different for each call). This of course means that the non-static version will need todo a lot more work than the static one (i.e. initializing all elements)... but that will be in the stack (most probabily in L1 cache), the static version instead will be in global memory that may be in cache or may be not depending on the real usage pattern and therefore it's not absurd to think that may be the non-static version can actually be faster in some scenario.

But you need real code with real data (and chose the hardware platform) to do a serious profiling... otherwise, as usual, it depends.

Sign up to request clarification or add additional context in comments.

6 Comments

A good compiler will not even call the function or perform the loop, and just contain return 0;.
Yet the OP observes a consistent pattern of the static version being faster, so it seems that their compiler is not optimizing the two to the same thing, whether it could do notwithstanding.
FWIW, I see the opposite pattern in my own initial tests.
@JohnBollinger: or the OP is not using optimization. Or s/he is seeing something that is not there (humans are very prone to see patterns and causality where none is present).
Yes that may be that tbh, my bad on there, I've not pushed the tests very far. Still, what if the array is really used through an important program, I don't have any example in mind but anyway, what will happen there ? Edit: The Edit above gave the answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.