Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes pointers faster than arrays?

Tags:

c

I was googling and found the following syntax for pointers

  void main()
 {
  char a[10]="helloworld";
  char *p=a;
  printf("%c",p[0]);
 }

I didnt know that Pointers can be accessed in the array form too. I used to use * for pointer operations I used a[0] for arrays and *p for pointer operations, which is why I didnt know the other 2 things. Now from the above, we can access the second element of array in any one of the following ways

  printf("%C",a[1]);   \\ this is the array
  printf("%c",*(a+1));  \\ this is the array using *
  printf("%c", p[1]);     \\ using the pointer 
  printf("%C",*(p+1));    \\ using the pointer

Now I wonder: which is the faster operation? I read that operations using pointers are faster, and that this is why C stays at the top for fast execution and that no other language can beat its fastness.

Now the real question: What makes the pointer operations faster?

1) *(p+0) the *(Value at address) that makes the trick or

2) p[0]

since we use

 *(a+1) or *(p+1) both are same 
  a[1] or p[1] both are same 

when a normal array can be used as *(a+1)( which uses * value at address) like a pointer. why do we use pointers for faster operations? When both have the same syntax, when normal array and pointer uses * in those syntaxes why pointers are faster?

But guys please tell me then why we use pointers ? My professor told me pointers are faster because they point to address rather a variable should be searched in the location.

like image 650
niko Avatar asked Aug 31 '11 17:08

niko


2 Answers

I wouldn't actually expect *(ptr + offset) to be faster than ptr[offset]. In fact, on my machine, the following functions are compiled into exactly the same assembly code:

int
ArrayRef(int* array, int index)
{
    return array[index];
}

int
PointerRef(int* array, int index)
{
    return *(array + index);
}

which (cleaned up) looks like:

ArrayRef:
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movl    %esi, -12(%rbp)
    movl    -12(%rbp), %eax
    cltq
    salq    $2, %rax
    addq    -8(%rbp), %rax
    movl    (%rax), %eax
    leave
    ret

PointerRef:
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movl    %esi, -12(%rbp)
    movl    -12(%rbp), %eax
    cltq
    salq    $2, %rax
    addq    -8(%rbp), %rax
    movl    (%rax), %eax
    leave
    ret

(gcc 4.5.0, x86_64, no optimisations). Or with -O3

ArrayRef:
    movslq  %esi, %rsi
    movl    (%rdi,%rsi,4), %eax
    ret

PointerRef:
    movslq  %esi, %rsi
    movl    (%rdi,%rsi,4), %eax
    ret
like image 145
Dirk Avatar answered Oct 05 '22 16:10

Dirk


Array access is faster if the array is allocated in the local stack scope or in static memory since it can be directly accessed via an offset of the value in the EBP register or via a direct offset from a fixed address, rather than attempting to access the value of a pointer in a stack variable, and then adding to that variable's value and dereferencing.

For instance, if you write you array like:

int main()
{
    int array[5] = {1, 2, 3, 4, 5};
    //... more code

    return 0;
}

In order to access the value at array[3], the complier will only issue a simple command like (this is for x86):

MOV -8(%ebp), %eax

This is because if we look at the stack, we would see the following:

EBP + 4 : Return Address
EBP     : Previous function's stack activation record
EBP - 4 : array[4]
EBP - 8 : array[3]
EBP - 12: array[2]
EBP - 16: array[1]
EBP - 20: array[0]

So in order to access the value at array[3], only one instruction is needed. That's very fast.

like image 28
Jason Avatar answered Oct 05 '22 17:10

Jason