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.
If you use them carefully, pointers can reduce the amount of program code you need to write, thereby increasing your program's efficiency and enabling you to use less memory. (Your program can run faster because it does not have to duplicate the data in memory).
Pointers are used to store and manage the addresses of dynamically allocated blocks of memory. Such blocks are used to store data objects or arrays of objects. Most structured and object-oriented languages provide an area of memory, called the heap or free store, from which objects are dynamically allocated.
2.2 Pointers Can Be Dangerous Because pointers provide access a memory location and because data and executable code exist in memory together, misuses of pointers can lead to both bizarre effects and very subtle errors. dangling pointers.
Pointers save memory space. Execution time with pointers is faster because data are manipulated with the address, that is, direct access to memory location.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With