0

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:

  • copying the attributes and accessing them within the loop
  • Accessing the attributes within the loop
  • Or maybe using an iterator over the attribute

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)

Community
  • 1
  • 1
Igor OA
  • 387
  • 3
  • 13
  • single-threaded access or multi-threaded? – Richard Hodges Jun 15 '16 at 12:34
  • Please read about references, const-references and const-correctness –  Jun 15 '16 at 12:35
  • 1./ Do not wonder about low level optimization in early development stages. 2./ If it already works and needs to be optimized, profile it to know what part is time expensive. 3./ Good C coding style means easy to read and maintain. – Serge Ballesta Jun 15 '16 at 12:44

3 Answers3

2

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thanks! Unfortunately, comparing the approaches wouldn't give me a sense of what is going on and why one is better/faster. But you partly answered me by teaching me that the main differences depend on the compiler - which I didn't suspect. – Igor OA Jun 15 '16 at 12:43
  • @IgorOA once you've found if one is faster, *then* you can ask the question *why is this faster than that on this compiler with these settings on this cpu?*. – eerorika Jun 15 '16 at 13:30
0

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.

John Burger
  • 3,662
  • 1
  • 13
  • 23
  • I like the pointer idea because it's simple, but I cannot think that accessing a vector element is not inlined to the direct access to the underlying array... – Serge Ballesta Jun 15 '16 at 12:40
  • I would expect an iterator implementation to be equivalent to the pointers solution - at least a good one. Not sure about what compilers actually do, though... – Aconcagua Jun 15 '16 at 13:07
-1

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.

SergeyA
  • 61,605
  • 5
  • 78
  • 137