Reputation: 17268
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
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
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
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
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
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
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