Igor OA
Igor OA

Reputation: 397

C++ - Loop Efficiency: Storing temporarly values of a class member Vs pointer to this member

Within a class method, I'm accessing private attributes - or attributes of a nested class. Moreover, I'm looping over these attributes.

I was wondering what is the most efficient way in terms of time (and memory) between:

I feel my question is related to : Efficiency of accessing a value through a pointer vs storing as temporary value. But in my case, I just need to access a value, not change it.

Example

Given two classes

class ClassA
{
 public:
       vector<double> GetAVector() { return AVector; }           

 private:
       vector<double> m_AVector;
}

and

class ClassB 
{
 public:
    void MyFunction();

 private:
    vector<double> m_Vector;
    ClassA m_A;
}

I. Should I do:

1.

void ClassB::MyFunction()
{
    vector<double> foo;
    for(int i=0; i<... ; i++)
    {
         foo.push_back(SomeFunction(m_Vector[i]));
    }
    /// do something ...
}

2.

void ClassB::MyFunction()
{
    vector<double> foo;
    vector<double> VectorCopy = m_Vector;
    for(int i=0; i<... ; i++)
    {
         foo.push_back(SomeFunction(VectorCopy[i]));
    }
    /// do something ...
}

3.

void ClassB::MyFunction()
{
    vector<double> foo;
    for(vector<double>::iterator it = m_Vector.begin(); it != m_Vector.end() ; it++)
    {
         foo.push_back(SomeFunction((*it)));
    }
    /// do something ...
}

II. What if I'm not looping over m_vector but m_A.GetAVector()?

P.S. : I understood while going through other posts that it's not useful to 'micro'-optimize at first but my question is more related to what really happens and what should be done - as for standards (and coding-style)

Upvotes: 0

Views: 136

Answers (3)

SergeyA
SergeyA

Reputation: 62553

Without optimizations, option 2 would be slower on every imaginable platform, becasue it will incur copy of the vector, and the access time would be identical for local variable and class member.

With optimization, depending on SomeFunction, performance might be the same or worse for option 2. Same performance would happen if SomeFunction is either visible to compiler to not modify it's argument, or it's signature guarantees that argument will not be modified - in this case compiler can optimize away the copy altogether. Otherwise, the copy will remain.

Upvotes: -1

John Burger
John Burger

Reputation: 3672

I can categorically say that 2. is less efficient than 1. Copying to a local copy, and then accessing it like you would the original would only be of potential benefit if accessing a stack variable is quicker than accessing a member one, and it's not, so it's not (if you see what I mean).

Option 3. is trickier, since it depends on the implementation of the iter() method (and end(), which may be called once per loop) versus the implementation of the operator [] method. I could irritate some C++ die-hards and say there's an option 4: ask the Vector for a pointer to the array and use a pointer or array index on that directly. That might just be faster than either!

And as for II, there is a double-indirection there. A good compiler should spot that and cache the result for repeated use - but otherwise it would only be marginally slower than not doing so: again, depending on your compiler.

Upvotes: 0

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

You're in luck: you can actually figure out the answer all by yourself, by trying each approach with your compiler and on your operating system, and timing each approach to see how long it takes.

There is no universal answer here, that applies to every imaginable C++ compiler and operating system that exists on the third planet from the sun. Each compiler, and hardware is different, and has different runtime characteristics. Even different versions of the same compiler will often result in different runtime behavior that might affect performance. Not to mention various compilation and optimization options. And since you didn't even specify your compiler and operating system, there's literally no authoritative answer that can be given here.

Although it's true that for some questions of this type it's possible to arrive at the best implementation with a high degree of certainty, for most use cases, this isn't one of them. The only way you can get the answer is to figure it out yourself, by trying each alternative yourself, profiling, and comparing the results.

Upvotes: 2

Related Questions