intrigued_66
intrigued_66

Reputation: 17268

Pointers and performance implications?

Are there performance implications when using pointers?

Is it better to avoid using pointers and if so, under what circumstances? Obviously they help, along with references, to reduce data copying. I presume if the data type being pointed to is small, the need for a pointer is smaller. In contrast, it is better to pass a large object via pointer as the overhead of the pointer is smaller than the overhead of copying the object.

I was also wondering about pointers in areas other than arguments/parameters?

Are references generally better than pointers in this performance context?

I appreciated I am bordering on the SO "dirty" topic of micro-optimizations but I am writing a very latency-focussed app.

Upvotes: 5

Views: 1591

Answers (6)

victor.t
victor.t

Reputation: 454

It depends on where is pointer pointing to. If object allocated on stack and you pass pointer parameter in many cases will be faster than pointer that points to object on heap. If object you passing was actively used in function before most of the chances it was already cached by CPU so then performance will be about the same.

About copying ... Most of the compilers will use CPU registers to pass pointers that's the fastest memory available in CPU. However if you'll pass as value compiler will require to copy whole object and also call ctor / dtor.

So my advice try keep things on stack and pass by pointers / references.

It's hard to say about performance it something that not constant and may change on different hardware / OS / compilers, so my advice is to profile the code with profiler tool to analyse things like cache misses, memory fragmentation, cpu usage.

http://en.wikipedia.org/wiki/VTune

http://developer.amd.com/tools/CodeAnalyst/Pages/default.aspx

Upvotes: 1

MrFox
MrFox

Reputation: 1254

Accessing data through a pointer is a little slower than doing it directly, but the dereference operation is very fast and this is usually not a big deal unless you are doing some very specific repetative number crunching tasks.

You are exactly correct about passing pointers for big vs. small objects. For example, the size of int* and int may be the same depending on the implementation.

References and pointers are usually the same with regards to performance. However, if you are in the habit of doing const Foo& rather than Foo*, the compilers can frequently do a better job optimiznig your code.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258648

Are references generally better than pointers in this performance context?

Yes, use references when you can, pointers when you must. Performance-wise, they are the same.

It's usually better to pass large structures by reference or pointer to prevent the extra copying, yes.

Accessing a variable or object through a pointer or reference may be just as fast as accessing it directly. The reason for this efficiency lies in the way microprocessors are constructed. All non-static variables and objects declared inside a function are stored on the stack and are in fact addressed relative to the stack pointer. Likewise, all non-static variables and objects declared in a class are accessed through the implicit pointer known in C++ as 'this'. We can therefore conclude that most variables in a well-structured C++ program are in fact accessed through pointers in one way or another. Therefore, microprocessors have to be designed so as to make pointers efficient, and that's what they are.

There are some disadvantages though, but they apply to both pointers and references:

However, there are disadvantages of using pointers and references. Most importantly, it requires an extra register to hold the value of the pointer or reference. Registers are a scarce resource, especially in 32-bit mode. If there are not enough registers then the pointer has to be loaded from memory each time it is used and this will make the program slower. Another disadvantage is that the value of the pointer is needed a few clock cycles before the time the variable pointed to can be accessed.

And here is the source. If you asked this question, I imagine you'll find it a good read.

Let's look at some code:

   int x = 0;
00412E0E  mov         dword ptr [x],0 
   foo(x);
00412E15  lea         eax,[x] 
00412E18  push        eax  
00412E19  call        foo (4111C2h) 
00412E1E  add         esp,4 
   foo(&x);
00412E21  lea         eax,[x] 
00412E24  push        eax  
00412E25  call        foo (4111BDh) 
00412E2A  add         esp,4 

No difference when calling the functions.

void foo (int& x)
{
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0C0h 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0C0h] 
00411382  mov         ecx,30h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
   x = 3;
0041138E  mov         eax,dword ptr [x] 
00411391  mov         dword ptr [eax],3 
}

void foo (int* x)
{
004117A0  push        ebp  
004117A1  mov         ebp,esp 
004117A3  sub         esp,0C0h 
004117A9  push        ebx  
004117AA  push        esi  
004117AB  push        edi  
004117AC  lea         edi,[ebp-0C0h] 
004117B2  mov         ecx,30h 
004117B7  mov         eax,0CCCCCCCCh 
004117BC  rep stos    dword ptr es:[edi] 
   *x = 3;
004117BE  mov         eax,dword ptr [x] 
004117C1  mov         dword ptr [eax],3 
}

No difference inside the functions.

Upvotes: 4

Matthieu M.
Matthieu M.

Reputation: 300349

I know that performance can be important, but semantics are more important: fast and wrong is useless.

Using pointers or references have semantics implications, such as sharing:

void foo(A& a) {
    a.a = 1;
    if (a.b != 0) { throw ... }
    a.b = 0;
}

In the case a.b == 0, then the first field of a has been changed but not its second.

Also, such sharing may create potential aliasing:

void foo(struct A a, struct A b);

void foo(struct A* a, struct A* b);

In the first case, the two structures are necessarily distinct, but in the latter they are not. This possible aliasing might prevent optimizations.

Focus on semantics first. Once you get them right, you can tweak and measure the effects in your particular situation.

Upvotes: 7

gbjbaanb
gbjbaanb

Reputation: 52689

your biggest problem with heap-based objects is that they will often not be located together when you need them, which means you require a lot more time to read those objects into the CPUs cache to work on them (ie, if you had 10 objects that you needed to work with, if they were all allocated contiguously a single memory read would shove them all into cache in one go, if they are scattered all over the heap, then a read for each of them is required).

To be fair, this applies to all heap systems, including garbage collected ones even after a garbage compaction. The answer (obviously) is to allocate these objects together, or to provide a buffer with free space to allocate them into over time.

The other problem with pointers is that you require an indirection to access the pointer-to objects. If you have an array of objects, you're fine - they are usually contiguous. But if you have an array of pointers, you'll have to read those pointers in order to find out where to read the objects.

Now, pointers can be fast too - if you use pointer arithmetic to access your contiguous objects (as you only need a single pointer read to find out where all the objects are).

So in short, the problem isn't with pointers themselves, but with how you organise the data they point to.

Upvotes: 1

chasques
chasques

Reputation: 140

Using pointers has no performance implications. The use of pointers is very fast. Pointers are used as a common tool in most (all?) professional projects. They are use to build lists, queues, maps, trees, data bases, every where. Get used to them!!!

Upvotes: -2

Related Questions