[ACCEPTED]-C++ performance of accessing member variables versus local variables-performance

Accepted answer
Score: 59

Executive summary: In virtually all scenarios, it 35 doesn't matter, but there is a slight advantage 34 for local variables.

Warning: You are micro-optimizing. You 33 will end up spending hours trying to understand 32 code that is supposed to win a nanosecond.

Warning: In 31 your scenario, performance shouldn't be 30 the question, but the role of the variables 29 - are they temporary, or state of thisClass?

Warning: First, second 28 and last rule of optimization: measure!

First 27 of all, look at the typical assembly generated 26 for x86 (your platform may vary):

// stack variable: load into eax
mov eax, [esp+10]

// member variable: load into eax
mov ecx, [adress of object]
mov eax, [ecx+4]

Once the 25 address of the object is loaded, int a register, the 24 instructions are identical. Loading the 23 object address can usually be paired with 22 an earlier instruction and doesn't hit execution 21 time.

But this means the ecx register isn't 20 available for other optimizations. However, modern 19 CPUs do some intense trickery to make that 18 less of an issue.

Also, when accessing many 17 objects this may cost you extra. However, this 16 is less than one cycle average, and there 15 are often more opprtunities for pairing 14 instructions.

Memory locality: here's a chance 13 for the stack to win big time. Top of stack 12 is virtually always in the L1 cache, so 11 the load takes one cycle. The object is 10 more likely to be pushed back to L2 cache 9 (rule of thumb, 10 cycles) or main memory 8 (100 cycles).

However, you pay this only for the 7 first access. if all you have is a single 6 access, the 10 or 100 cycles are unnoticable. if 5 you have thousands of accesses, the object 4 data will be in L1 cache, too.

In summary, the 3 gain is so small that it virtually never 2 makes sense to copy member variables into 1 locals to achieve better performance.

Score: 8

I'd prefer the local variables on general 5 principles, because they minimize evil mutable 4 state in your program. As for performance, your 3 profiler will tell you all you need to know. Locals 2 should be faster for ints and perhaps other 1 builtins, because they can be put in registers.

Score: 4

This should be your compilers problem. Instead, optimize 13 for maintainability: If the information 12 is only ever used locally, store it in local 11 (automatic) variables. I hate reading classes 10 littered with member variables that don't 9 actually tell me anything about the class 8 itself, but only some details about how 7 a bunch of methods work together :(

In fact, I 6 would be surprised if local variables aren't 5 faster anyway - they are bound to be in 4 cache, since they are close to the rest 3 of the functions data (call frame) and an 2 objects pointer might be somewhere totally 1 else - but I am just guessing here.

Score: 2

Silly question.
It all depends on the compiler 9 and what it does for optimization.

Even if 8 it did work what have you gained? Way to 7 obfuscate your code?

Variable access is usually 6 done via a pointer and and offset.

  • Pointer to Object + offset
  • Pointer to Stack Frame + offset

Also don't 5 forget to add in the cost of moving the 4 variables to local storage and then copying 3 the results back. All of which could be 2 meaning less as the compiler may be smart 1 enough to optimize most of it away anyway.

Score: 2

A few points that have not been mentioned 13 explicitly by others:

  • You are potentially 12 invoking assignment operators in your code. e.g 11 varC = msg.getString();

  • You have some wasted 10 cycles every time the function frame is 9 setup. You are creating variables, default 8 constructor called, then invoke the assignment 7 operator to get the RHS value into the locals.

  • Declare 6 the locals to be const-refs and, of course, initialize 5 them.

  • Member variables might be on the heap(if 4 your object was allocated there) and hence 3 suffer from non-locality.

  • Even a few cycles 2 saved is good - why waste computation time 1 at all, if you could avoid it.

Score: 1

When in doubt, benchmark and see for yourself. And 7 make sure it makes a difference first - hundreds 6 of times a second isn't a huge burden on 5 a modern processor.

That said, I don't think 4 there will be any difference. Both will 3 be constant offsets from a pointer, the 2 locals will be from the stack pointer and 1 the members will be from the "this" pointer.

Score: 1

In my oppinion, it should not impact performance, because:

  • In Your first example, the variables are accessed via a lookup on the stack, e.g. [ESP]+4 which means current end of stack plus four bytes.
  • In the second example, the variables are accessed via a lookup relative to this (remember, varB equals to this->varB). This is a similar machine instruction.

Therefore, there 2 is not much of a difference.

However, You 1 should avoid copying the string ;)

Score: 1

The amount of data that you will be interacting 32 with will have a bigger influence on the 31 execution speed than the way you represent 30 the data in the implementation of the algorithm.

The 29 processor does not really care if the data 28 is on the stack or on the heap (apart from 27 the chance that the top of the stack will 26 be in the processor cache as peterchen mentioned) but 25 for maximum speed, the data will have to 24 fit into the processor's cache (L1 cache 23 if you have more than one level of cache, which 22 pretty much all modern processors have). Any 21 load from L2 cache - or $DEITY forbid, main 20 memory - will slow down the execution. So 19 if you're processing a string that's a few 18 hundred KB in size and chances on every 17 invocation, the difference will not even 16 be measurable.

Keep in mind that in most 15 cases, a 10% speedup in a program is pretty 14 much undetectable to the end user (unless 13 you manage to reduce the runtime of your 12 overnight batch from 25h back to less than 11 24h) so this is not worth fretting over 10 unless you are sure and have the profiler 9 output to back up that this particular piece 8 of code is within the 10%-20% 'hot area' that 7 has a major influence over your program's 6 runtime.

Other considerations should be more 5 important, like maintainability or other 4 external factors. For example if the above 3 code is in heavily multithreaded code, using 2 local variables can make the implementation 1 easier.

Score: 1

It depends, but I expect there would be 9 absolutely no difference.

What is important 8 is this: Using member variables as temporaries 7 will make your code non-reentrant - For 6 example, it will fail if two threads try 5 to call callback() on the same object. Using 4 static locals (or static member variables) is 3 even worse, because then your code will 2 fail if two threads try to call callback() on 1 any thisClass object - or descendant.

Score: 0

Using the member variables should be marginally 7 faster since they only have to be allocated 6 once (when the object is constructed) instead 5 of every time the callback is invoked. But 4 in comparison to the rest of the work you're 3 probably doing I expect this would be a 2 very tiny percentage. Benckmark both and 1 see which is faster.

Score: 0

Also, there's a third option: static locals. These 4 don't get re-allocated every time the function 3 is called (in fact, they get preserved across 2 calls) but they don't pollute the class 1 with excessive member variables.

More Related questions