Reputation: 5073
I have been reading a book which says that accessing array elements by pointer arithmetic's is much faster than the [] operator. In short this code is faster than this code. The book does not say why. Is it advisible to use such pointer arithmetic's even if it provides significant improvement in speed?
#include <iostream>
using namespace std;
int main() {
// your code goes here
double *array = new double[1000000];
for(int i = 0; i < 1000000; i++)
{
array[i] = 0;//slower?
}
delete[] array;
return 0;
}
#include <iostream>
using namespace std;
int main() {
// your code goes here
double *array = new double[1000000];
for(int i = 0; i < 1000000; i++)
{
*(array + i) = 0;//faster?
}
delete[] array;
return 0;
}
EDIT:
Quote from book pg 369, 2nd last line
The pointer accessing method is much faster than array indexing.
Upvotes: 5
Views: 152
Reputation: 158459
There is no difference at all, if we go to the draft C++ standard section 5.2.1
Subscripting paragraph 1 says (emphasis mine):
[...]The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. —end note ]
Upvotes: 2
Reputation: 64895
The book is just plain wrong - especially if those are the actual examples they gave. Decent compilers are likely to produce identical code for both methods, even without optimization and they will have identical performance.
Without optimization, or with compilers from the 80s, you might get performance differences with some types of pointer arithmetic, but the examples don't even represent that case. The examples are basically just different syntax for the same thing.
Here's an example that could plausibly have a performance difference (versus the array index case which is unchanged):
int main() {
// your code goes here
double *array = new double[1000000], *ptr = array;
for(; ptr < array + 1000000; ptr++)
{
*ptr = 0;
}
return 0;
}
Here, you aren't indexing against the base pointer each time through the loop, but are incrementing the pointer each time. In theory, you avoid the multiplication implicit in indexing, resulting in a faster loop. In practice, any decent compiler can reduce the indexed form to the additive form, and on modern hardware the multiplication by sizeof(double)
implied by indexing is often free as part of an instruction like lea
(load effective address), so even at the assembly level the indexed version may not be slower (and may in fact be faster since it avoids a loop-carried dependency and also lends itself better to aliasing analysis).
Upvotes: 1
Reputation: 5083
Your two forms are the same, you're not really doing pointer arithmetic.
The pointer form would be:
double * array= new double[10000000] ;
double * dp= array ;
for ( int i= 0 ; ( i < 10000000 ) ; i ++, dp ++ )
{
* dp= 0 ;
}
Hear, the address in dp
is moved to the next one via an add. In the other forms, the address is calculated each go through the loop by multiplying i
time sizeof(double) and adding it to array
. Its the multiply that historically was slower than the add.
Upvotes: -1
Reputation: 2150
Array indices are just syntactic sugar for pointer arithmetic. Your compiler will boil down a[i]
into *((a) + (i))
. Agreed, run away from that book!
For more in-depth explanations, see
Upvotes: 2
Reputation: 26040
Utter rubbish. a[x]
on a plain array decays into *(a + x)
. There will literally be 0 performance difference.
Upvotes: 1
Reputation: 76240
No, they are exactly the same thing. I definitely suggest you to drop that book and pick another one up as soon as possible.
And even if there was any performance difference, the clarity of x[12]
over *(x + 12)
is much more important.
Upvotes: 5