3

I have a function, where I use a array of constants:

void function(int Id){
int array1[4] = {4 constants};
int array2[4] = {4 constants};
   for(int i=0; i<4; i++){
   //accessing the array 1&2 for computation;
   }
}

There would be nearly million times the void function(int Id) would be accessed from main().

My question is, whether it is better to declare the array1 and array2 in a header file and access inside function(), or is it better to declare them on the fly as it is now?

Which way would be faster (considering accessing from header file or declaring on the fly)?

Edit: Arrays are only accessed and are not modified inside function().

SKPS
  • 5,433
  • 5
  • 29
  • 63
  • The initializers are constant, but are the arrays immutable or are you changing them inside the function? – Joachim Isaksson Sep 12 '13 at 13:21
  • 1
    How about running an experiment. Try it both ways. Your compiler is probably smart enough to optimize lots of constant values for you. – Paul Rubel Sep 12 '13 at 13:22
  • Arrays are not modified inside function – SKPS Sep 12 '13 at 13:22
  • 1
    What are you ACTUALLY doing inside the loop? Have you profiled the code to actually determine that this particular bit is a problem? Is `function` available to the compiler so that it can be inlined? – Mats Petersson Sep 12 '13 at 13:23
  • 2
    If the arrays are not modified inside the function, you're probably best off defining them `static int const array...`. – James Kanze Sep 12 '13 at 13:25

4 Answers4

15

If the arrays are not going to change, and are not going to be reused in another function, you might be better making them static. This avoids the necessity of the arrays being constructed on the stack on each call of your function.

void function(int Id){
    static const int array1[4] = {4 constants};
    static const int array2[4] = {4 constants};
    for(int i=0; i<4; i++){
        //accessing the array 1&2 for computation;
   }
}

edit to add It would be good practice to avoid using the "magic number" 4 in your array declaration and loop expression. If this isn't done it's easy to change the array size and forget to change the loop expression. This can be done either by making the array size a constant, or by using sizeof() in your loop expression as shown in this stack overflow question: How do I determine the size of my array in C?

Community
  • 1
  • 1
Simon Elliott
  • 2,087
  • 4
  • 30
  • 39
  • 3
    The other advantage of this method is that the arrays are only visible within the function; they're not exposed to the rest of the program unnecessarily. – John Bode Sep 12 '13 at 15:29
5

I think the best way to do it is:

void function(int Id){
    static const int array1[4] = {4 constants};
    static const int array2[4] = {4 constants};
   for(int i=0; i<4; i++){
   //accessing the array 1&2 for computation;
   }
}

But it would be better to just make a small test to see which one is fastest. Raxvan.

Raxvan
  • 6,257
  • 2
  • 25
  • 46
  • Also if your function is that critical for performance you might want to look into aliasing problems and other compiler specific optimizations such as this one: http://msdn.microsoft.com/en-us/library/k649tyc7.aspx – Raxvan Sep 12 '13 at 13:30
  • 3
    Try adding a bit of explanation to your solutions. More often than not people are here to learn and not simply get a fix for their problem. (well probably a bit of both) – Don Sep 12 '13 at 13:35
2

I would guess no difference. You might want to write:

**const** int array1[4]

to better explain to the compiler what you mean. That may give it more options to make optimizations.

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
0

I tried a test case which compares the three options - global, local, local static for about 20 million ops of a simple vector inner product for 4d vectors. This was done on VS2010 32-bit release version. Here's the result:

DPSUM:600000000 TIME:78| DPSUM:600000000 TIME:62| DPSUM:600000000 TIME:63| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:46| DPSUM:600000000 TIME:78| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:78| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:62| DPSUM:600000000 TIME:62| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:63| DPSUM:600000000 TIME:46| DPSUM:600000000 TIME:63| DPSUM:600000000 TIME:62| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:78| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:46| DPSUM:600000000 TIME:78| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:62| DPSUM:600000000 TIME:63| DPSUM:600000000 TIME:47| DPSUM:600000000 TIME:62|

The first column is the static const, second is local and the third is global. I'm posting the sample code if you want to try on your platform. Looks like static local and local are equally fast - at least for this compiler (maybe due to some internal optimization.

Code below:

#include <stdio.h>
#include <windows.h>

int ag[] = {1,2,3,4}; int bg[] = {1,2,3,4};
int dp1(){
    static const int a[] = {1,2,3,4}; static const int b[] = {1,2,3,4};
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
}

int dp2(){
    int a[] = {1,2,3,4}; int b[] = {1,2,3,4};
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
}

int dp3(){
    return ag[0]*bg[0] + ag[1]*bg[1] + ag[2]*bg[2] + ag[3]*bg[3];
}

int main(){
    int numtrials = 10;
    typedef int (*DP)();
    DP dps[] = {dp1, dp2, dp3};

    for (int t = 0; t < numtrials; ++t){
        int dpsum[] = {0,0,0};
        for (int jj =0; jj <3; ++jj){
            DWORD bef, aft;
            bef = GetTickCount();
            for (int ii =0; ii< 20000000; ++ii){
                dpsum[jj] += dps[jj]();
            }
            aft = GetTickCount();
            printf("DPSUM:%d TIME:%d| ", dpsum[jj], aft - bef);
        }
        printf("\n");
    }
    getchar();
}
Arun R
  • 873
  • 6
  • 10
  • Just to note, under reasonable optimizations (which VC may or may not be doing), `dp1` and `dp2` should both optimize to a single `return ` statement. – Bill Lynch Sep 12 '13 at 14:16