开发者

C and C++: Array element access pointer vs int

开发者 https://www.devze.com 2022-12-30 11:51 出处:网络
Is there a performance difference if you either do myarray[ i ] or store the adress of myarray[ i ] in a pointer?

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.


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.


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.


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++.


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.


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.


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.


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.


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


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号