views:

177

answers:

10

Is there a performance difference if you either do myarray[ i ] or store the adress of myarray[ i ] in a pointer?

Edit: The pointers are all calculated during an unimportant step in my program where performance is no criteria. During the critical parts the pointers remain static and are not modified. Now the question is if these static pointers are faster than using myarray[ i ] all the time.

+2  A: 

I prefer using myarray[ i ] since it is more clear and the compiler has easier time compiling this to optimized code.

When using pointers it is more complex for the compiler to optimize this code since it's harder to know exactly what you're doing with the pointer.

brickner
I'm building an interpreter and it is about access speed for variables and constant values, idk if that changes the answer
begun
Your interpreter would still be compiled using c/c++ compiler. This compiler would have easier time compiling standard code that uses access by index using [] operator instead of using pointer arithmetic. The compiler won't perform worse since it can easily optimize your code to work with pointers if it is better. It would also have easier time doing loop unrolling and other compilation optimizations.
brickner
I don't perform **any** pointer arithmetic in the interpretation phase. All pointers are calculated during the parsing step and remain unchanged then.
begun
-1: The performance is worse only at compile time, not at runtime. Is this relevant?
Simon
You never increment a pointer? Are the addresses always constant?
brickner
The performance can be worse at run time.
brickner
Yes. The adresses are determined during the parsing step where variable names are assigned spaces in the variable table. Then the variable names are replaced by pointers pointing to the right location in the variable table. The location never changes.
begun
@brickner, pointer arithmetic and `[]` are the same, complexity-wise, both at compile-time and runtime. `*(a + i)` is identical to `a[i]` (and `i[a]`, for that matter).
Marcelo Cantos
So it doesn't matter if you use pointers or access using index performance wise. It does matter for readability and maintainability.
brickner
@Marcelo Cantos, if you do a loop on i and increment the pointer by one at each iteration (ptr++) or access using [i], incrementing the pointer is more complex for the compiler.
brickner
@brickner: If [] is pointer arithmetic it has to be slower than pointers that aren't changed or?
begun
@begun, No, because it is still the same number of operations in assembly.
brickner
@brickner, `ptr++` can be trivially implemented via a single opcode. How is that more complex?
Marcelo Cantos
@Marcelo Cantos, think about complex code with pointers you want to do loop unrolling for. It's harder to understand the number of iterations the loop has if you use pointer arithmetic.
brickner
@brickner, loop unrolling is predicated on the loop variable alone and will be completely unaffected by the pointer increment, which will get unrolled along with whatever other code is inside the body. In any event, we're seriously splitting hairs here.
Marcelo Cantos
A: 

Yes. Having a pointer the address won't be calculated by using the initial address of the array. It will accessed directly. So you have a little performance improve if you save the address in a pointer. But the compiler will usually optimize the code and use the pointer in both cases (if you have statical arrays)

For dynamic arrays (created with new) the pointer will offer you more performance as the compiler cannot optimize array accesses at compile time.

Simon
Unjustified -1. Compiler cannot optimize things known at runtime.
Simon
-1: simply not true, in general. You can't make sweeping generalisations like this without any evidence. If you take the time to benchmark some example code with different CPUs and different compilers you will find that in many cases the converse of your assertion is true.
Paul R
@Downvoter: Please state what is wrong with this answer so I know what not to do...
begun
So accessing an array by index is faster than/or as fast as accessing it by pointer, even for dynamical arrays whose size is known at runtime?
Simon
MSalters
A: 

Yes.. when storing myarray[i] pointer it will perform better (if used on large scale...)

Why??

It will save you an addition and may be a multiplication (or a shift..)

Many compilers may optimize that for you in case of static memory allocation. If you are using dynamic memory allocation, the compiler will not optimize it, because it is in runtime!

Betamoo
-1: this is an overly broad and mostly inaccurate generalisation
Paul R
+3  A: 

It will probably make no difference at all. The compiler will usually be smart enough to know when you are using an expression more than once and create a temporary itself, if appropriate.

Marcelo Cantos
+3  A: 

Compilers can do surprising optimizations; the only way to know is to read the generated assembly code.

With GCC, use -S, with -masm=intel for Intel syntax.

With VC++, use /FA (IIRC).

You should also enable optimizations: -O2 or -O3 with GCC, and /O2 with VC++.

Bastien Léonard
+1  A: 

There should not be much different but by using indexing you avoid all types of different pitfalls that the compiler's optimizer is prone to (aliasing being the most important one) and thus I'd say the indexing case should be easier to handle for the compiler. This doesn't mean that you should take care of aforementioned things before the loop, but pointers in a loop generally just adds to the complexity.

nj
A: 

There will be no substantial difference. Premature optimization is the root of all evil - get a profiler before checking micro-optimizations like this. Also, the myarray[i] is more portable to custom types, such as a std::vector.

DeadMG
A: 

Okay so your questions is, whats faster:

int main(int argc, char **argv)
{
  int array[20];

  array[0] = 0;
  array[1] = 1;

  int *value_1 = &array[1];
  printf("%d", *value_1);
  printf("%d", array[1]);
  printf("%d", *(array + 1));
}

Like someone else already pointed out, compilers can do clever optimization. Of course this is depending on where an expression is used, but normally you shouldn't care about those subtle differences. All your assumption can be proven wrong by the compiler. Today you shouldn't need to care about such differences.

For example the above code produces the following (only snippet):

mov     [ebp+var_54], 1 #store 1
lea     eax, [ebp+var_58] # load the address of array[0]
add     eax, 4 # add 4 (size of int)
mov     [ebp+var_5C], eax
mov     eax, [ebp+var_5C]
mov     eax, [eax]
mov     [esp+88h+var_84], eax
mov     [esp+88h+var_88], offset unk_403000 # points to %d
call    printf
mov     eax, [ebp+var_54]
mov     [esp+88h+var_84], eax
mov     [esp+88h+var_88], offset unk_403000
call    printf
mov     eax, [ebp+var_54]
mov     [esp+88h+var_84], eax
mov     [esp+88h+var_88], offset unk_403000
call    printf
evilpie
+5  A: 

For this code:

int main() {
    int a[100], b[100];
    int * p = b;
    for ( unsigned int i = 0; i < 100; i++ ) {
        a[i] = i;
        *p++ = i;
    }
    return a[1] + b[2]; 
}

when built with -O3 optimisation in g++, the statement:

a[i] = i;

produced the assembly output:

mov    %eax,(%ecx,%eax,4)

and this statement:

*p++ = i;

produced:

mov    %eax,(%edx,%eax,4)

So in this case there was no difference between the two. However, this is not and cannot be a general rule - the optimiser might well generate completely different code for even a slightly different input.

anon
A: 

Short answer: the only way to know for sure is to code up both versions and compare performance. I would personally be surprised if there was a measureable difference unless you were doing a lot of array accesses in a really tight loop. If this is something that happens once or twice over the lifetime of the program, or depends on user input, it's not worth worrying about.

Remember that the expression a[i] is evaluated as *(a+i), which is an addition plus a dereference, whereas *p is just a dereference. Depending on how the code is structured, though, it may not make a difference. Assume the following:

int a[N]; // for any arbitrary N > 1
int *p = a;
size_t i;

for (i = 0; i < N; i++)
  printf("a[%d] = %d\n", i, a[i]);

for (i = 0; i < N; i++)
  printf("*(%p) = %d\n", (void*) p, *p++);

Now we're comparing a[i] to *p++, which is a dereference plus a postincrement (in addition to the i++ in the loop control); that may turn out to be a more expensive operation than the array subscript. Not to mention we've introduced another variable that's not strictly necessary; we're trading a little space for what may or may not be an improvement in speed. It really depends on the compiler, the structure of the code, optimization settings, OS, and CPU.

Worry about correctness first, then worry about readability/maintainability, then worry about safety/reliability, then worry about performance. Unless you're failing to meet a hard performance requirement, focus on making your intent clear and easy to understand. It doesn't matter how fast your code is if it gives you the wrong answer or performs the wrong action, or if it crashes horribly at the first hint of bad input, or if you can't fix bugs or add new features without breaking something.

John Bode