This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Arrays vs. Structures?

Other Parts Discussed in Thread: TMS320F28035

This is a general C question (executed on a TMS320F28035):

I can group a set of variables in a structure (which I normally see done in examples), or, in an array. My question is: from a compiler point of view, which is more optimal? For example, does a structure execute faster, or use less memory, than an array? Assume both are global.

Thanks!

-Brian

  • Brian,

    From the compiler's perspective these are both equivalent in terms of memory usage and access speed for static members.  There may be a speed difference though depending on how you are accessing members of each.  What I mean is that the speed is highly dependent on the addressing mode the compiler generates for the MOV instruction.  You can read about this in the C28x Instruction Set Reference Guide.

    Unless you are really trying to squeeze out every last ounce of performance I wouldn't worry about this.  Implement your software in a way that is easy for you (and others) to understand and maintain.  You'll thank me in 3 or 4 years ;-)

    Trey

  • Brian I. said:
    I can group a set of variables in a structure

    Not sure that it's quite right to speak of a struct or array as a "set of variables"?

    More usually considered a single variable with a number of fields or elements. An Aggregate Type in the language of the 'C' specification.

    Anyhow, the key distinguising factor between a struct and an array is that a struct may contain fileds of different types, while all elements of an array must be of the same type.

    The methods of access also differ:

    • fields of a struct are accessed by name;
    • elements of an array are accessed by index.

     

  • I think it depends on the test case. Let's say you have 4 variables:

    int a;
    int b;
    int c;
    int d;

    You can group them into a structure:

    typedef struct
    {
      int a;
      int b;
      int c;
      int d;
    } SOME_STRUCT;

    SOME_STRUCT mystruct;

    Or group them into an array:

    #define A_OFFSET 0
    #define B_OFFSET 1
    #define C_OFFSET 2
    #define D_OFFSET 3
    int myarray[4];

    Some example code copying from one representation to another.

    void copy(SOME_STRUCT *p, int a[])
    {
      p->a  = a[A_OFFSET];
      p->b  = b[B_OFFSET];
      p->c  = c[C_OFFSET];
      p->d  = d[D_OFFSET];
    }

    In the above scenario, the representations are more or less equivalent. Same storage and I would guess the same efficiency in accessing any individual member.

    However the representation would matter if your variables are not all the same type and you have more than one instance. Suppose you had 1024 items which had 4 variables:

    #define N 1024
    int  a[N];
    char b[N];
    int  c[N];
    char d[N];

    The structure and declartion would then be:

    typedef struct
    {
      int  a;
      char b;
      int  c;
      char d;
    } SOME_STRUCT;

    SOME_STRUCT mystructs[N];

    The storage used by the structures would be greater than the arrays. This is due to the padding added to the structure for alignment. Let's say, your processor requires even alignment of int variables. The structure define effectively looks like this:

    typedef struct
    {
      int  a;
      char b;
      char pad_b;
      int  c;
      char d;
      char pad_d;
    } SOME_STRUCT;

    The structure would use 2 extra bytes per item. For 1024 items, that would be 2K of memory lost to padding.

    Some example code copying from one representation to another:

    void copy(SOME_STRUCT s[], int a[], char b[], int c[], char d[])
    {
      int i;
      for(i=0; i<N, i++)
      {
        s[i].a  = a[i];
        s[i].b  = b[i];
        s[i].c  = c[i];
        s[i].d  = d[i];
      }
    }

    The structure representation requires one parameter to be passed in. The arrays representation requires four. Pushing parameters onto the stack can take time and memory.

    Let's say you need to iterate through one member of each item. The structure code:

    int add_a(SOME_STRUCT s[])
    {
      int i;
      int a = 0;
      for(i=0; i<N; i++)
        i += s[i].a;
      return(i);
    }

    and the array version.

    int add_a(int a[])
    {
      int i;
      int a = 0;
      for(i=0; i<N; i++)
        i += a[i];
      return(i);
    }

    Depending on the platform, "s[i].a" is less efficient than "a[i]". As well, the array operation lends itself well to single instruction array operations on DSPs. The compiler may automatically do this for you.

    Let's say you need to process one item:

    void init(SOME_STRUCT *p)
    {
      p->a = 0;
      p->b = 0;
      p->c = 0;
      p->d = 0;
    }

    void init_all(SOME_STRUCT s[])
    {
      int i;
      for(i=0; i<N; i++)
        init(&s[i]);
    }

    and the array version.

    void init(int *a, char *b, int *c, char *d)
    {
      *a = 0;
      *b = 0;
      *c = 0;
      *d = 0;
    }

    void init_all(int a[], char b[], int c[], char d[])
    {
      int i;
      for(i=0; i<N; i++)
        init(&a[i], &b[i], &c[i], &d[i]);
    }

    I would guess that the structure version is more efficient.

  • I appreciate everyone's fast response, thank you very much. In particular, I appreciate Norman Wong's post; he put a lot of effort into his explanation.

    So it looks like the answer is "it depends", which is fine. Naturally, if one needs different data types, structures are the obvious way to go (which did not occur to me when I wrote my original post).