Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ fixed size arrays vs multiple objects of same type

I was wondering whether (apart from the obvious syntax differences) there would be any efficiency difference between having a class containing multiple instances of an object (of the same type) or a fixed size array of objects of that type.

In code:

struct A {
  double x;
  double y;
  double z;
};

struct B {
  double xvec[3];
};

In reality I would be using boost::arrays which are a better C++ alternative to C-style arrays.

I am mainly concerned with construction/destruction and reading/writing such doubles, because these classes will often be constructed just to invoke one of their member functions once.

Thank you for your help/suggestions.

like image 836
StephQ Avatar asked Jan 30 '11 15:01

StephQ


People also ask

What are 2 typical problems with fixed array sizes?

Because fixed arrays have memory allocated at compile time, that introduces two limitations: Fixed arrays cannot have a length based on either user input or some other value calculated at runtime. Fixed arrays have a fixed length that can not be changed.

Do arrays have fixed-size in C?

Arrays a kind of data structure that can store a fixed-size sequential collection of elements of the same type.

Does array have fixed-size?

An array is a data structure/container/object that stores a fixed-size sequential collection of elements of the same type. The size/length of the array is determined at the time of creation.

Can an array have multiple data types in C?

No, we cannot store multiple datatype in an Array, we can store similar datatype only in an Array.


1 Answers

Typically the representation of those two structs would be exactly the same. It is, however, possible to have poor performance if you pick the wrong one for your use case.

For example, if you need to access each element in a loop, with an array you could do:

for (int i = 0; i < 3; i++)
    dosomething(xvec[i]);

However, without an array, you'd either need to duplicate code:

dosomething(x);
dosomething(y);
dosomething(z);

This means code duplication - which can go either way. On the one hand there's less loop code; on the other hand very tight loops can be quite fast on modern processors, and code duplication can blow away the I-cache.

The other option is a switch:

for (int i = 0; i < 3; i++) {
    int *r;
    switch(i) {
        case 0: r = &x; break;
        case 1: r = &y; break;
        case 1: r = &z; break;
    }
    dosomething(*r); // assume this is some big inlined code
}

This avoids the possibly-large i-cache footprint, but has a huge negative performance impact. Don't do this.

On the other hand, it is, in principle, possible for array accesses to be slower, if your compiler isn't very smart:

xvec[0] = xvec[1] + 1;
dosomething(xvec[1]);

Since xvec[0] and xvec[1] are distinct, in principle, the compiler ought to be able to keep the value of xvec[1] in a register, so it doesn't have to reload the value at the next line. However, it's possible some compilers might not be smart enough to notice that xvec[0] and xvec[1] don't alias. In this case, using seperate fields might be a very tiny bit faster.

In short, it's not about one or the other being fast in all cases. It's about matching the representation to how you use it.

Personally, I would suggest going with whatever makes the code working on xvec most natural. It's not worth spending a lot of human time worrying about something that, at best, will probably only produce such a small performance difference that you'll only catch it in micro-benchmarks.

like image 199
bdonlan Avatar answered Nov 15 '22 07:11

bdonlan