简体   繁体   中英

Proper way of dealing with array of structs: all in one place vs splitting vs arrays within structs

I'm trying to find the most efficient way of dealing with array of sets of structs. Namely, at the moment I have got the following structure:

struct myStruct{
    double p1;
    double p2;
    bool p3;
    double w;
}

So, objects I modelling have three properties and a weight assigned to them. Now, these are arranged in arrays of fixed size, say, 10, and there are multiple combinations of the objects weights, say 1000 of them:

const int nObj = 10;
const int n = 1000;

myStruct comb[n][nObj];

And finally there are a couple of functions I'm passing 10-sized arrays to:

double evalComb(myStruct (&ms)[nObj], double q1, double q2){
    double output = 0;
    for(int i = 0; i < nObj; i++){
        output += // calculate some stuff using p1,p2,p3,w and other params
    }
    return output;
};

Now, the issue is that the set of ten values of p1 , p2 , p3 is fixed across all the 1000 combinations (but not const), the only thing changing is set of 10 weights w . This kind of makes me think it is a waste of memory copying all that 1000 times... I've got the working code but would like to make it quicker and my understanding is that this would be the most obvious place to optimize (as that function is called millions of times and the 90% of time goes there). Is is better to get weights out of the struct and have 2d double array of those leaving a 1d array of structs? That would mean another array parameter passed to a function, wouldn't it slow it down? Maybe I should have structs with arrays inside them instead? Any other issues which could arise with this?

What I would suggest is to have a class containing a double with three static members for the things that don't change.

struct myStruct{
    static std::array<double,10> p1;
    static std::array<double,10> p2;
    static std::array<bool,10> p3;
    double w;
}  

This way you save the space and still have easy access to the three other variables, IMO it is better to keep the class instead of just using an array of doubles because it preserves the association in between the variables and also gives you an opportunity to modify the class later on. Classes don't really cause as much overhead as you think especially with modern compilers.

You may also want to make the static variables const if they will never change

If the 10 values for p1, p2, and p3 never change make them constant or use #define. You'll get a performance increase when the compiler swaps them out in your method or function definitions with literals. An "object" in this case would just be an array of 10 doubles for w. You might also consider declaring w as a 1000 X 10 array to keep the memory allocated in a contiguous block. That will give you a performance increase over mixing variable types that are not memory address aligned in your struct.

If the p1, p2, p3 members are the same (common) for all of your 100 or so structures I'd like to propose a change to your design. You create a new class/structure for your properties

struct myProperties {
    // TODO: define c'tor
    double p1;
    double p2;
    bool p3;
};

struct myStruct {
      myStruct(myProperties *properties_): properties(properties_) {}
      myProperties properties;
      // TODO: define getters for p1, p2, p3
};

When creating a group of myStruct with the same properties you pass a pointer to a myProperties object with your desired properties

myProperties m(p1, p2, p3); 
myStruct s(&m);

This way you can have one property group (p1, p2, p3) assigned to one group of your 100 myStruct objects and another property group assigned to your other 1000 myStruct objects (you cannot achieve this with static members).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM