Нет, указатели никогда не должны быть быстрее индекса массива. Если один из кодов работает быстрее, чем другой, это происходит главным образом потому, что некоторые вычисления адресов могут отличаться. Вопрос также должен содержать информацию о компиляторе и флагах оптимизации, так как это может сильно повлиять на производительность.
Индекс массива в вашем контексте (граница массива неизвестна) в точности идентична операции с указателем. С точки зрения компиляторов, это просто другое выражение арифметики указателей. Вот пример оптимизированного кода x86 в Visual Studio 2010 с полной оптимизацией и без встроенного .
3: void myPointer(int a[], int size)
4: {
013E1800 push edi
013E1801 mov edi,ecx
5: int *p;
6: for(p = a; p < &a[size]; p++)
013E1803 lea ecx,[edi+eax*4]
013E1806 cmp edi,ecx
013E1808 jae myPointer+15h (13E1815h)
013E180A sub ecx,edi
013E180C dec ecx
013E180D shr ecx,2
013E1810 inc ecx
013E1811 xor eax,eax
013E1813 rep stos dword ptr es:[edi]
013E1815 pop edi
7: {
8: *p = 0;
9: }
10: }
013E1816 ret
13: void myIndex(int a[], int size)
14: {
15: int i;
16: for(i = 0; i < size; i++)
013E17F0 test ecx,ecx
013E17F2 jle myIndex+0Ch (13E17FCh)
013E17F4 push edi
013E17F5 xor eax,eax
013E17F7 mov edi,edx
013E17F9 rep stos dword ptr es:[edi]
013E17FB pop edi
17: {
18: a[i] = 0;
19: }
20: }
013E17FC ret
На первый взгляд, myIndex
выглядит быстрее, потому что количество инструкций меньше, однако две части кода по сути одинаковы. Оба в конечном итоге используют rep stos
, что является повторяющейся (циклической) инструкцией x86. Единственное отличие заключается в вычислении границы цикла. Цикл for
в myIndex
имеет счетчик отключений size
как есть (т.е. вычисление не требуется). Но для myPointer
нужны некоторые вычисления, чтобы получить счетчик циклов for
. Это единственная разница. Важные операции цикла точно такие же. Таким образом, разница незначительна.
Подводя итог, производительность myPointer
и myIndex
в оптимизированном коде должна быть одинаковой.
К вашему сведению, если граница массива известна во время компиляции, например, int A[constant_expression]
, тогда доступ к этому массиву может быть намного быстрее, чем указатель. Это происходит главным образом потому, что доступ к массиву свободен от проблемы анализа указателей . Компиляторы могут отлично вычислять информацию о зависимостях вычислений и обращений к массиву фиксированного размера, поэтому могут выполнять расширенную оптимизацию, включая автоматическое распараллеливание.
Однако, если вычисления основаны на указателе, компиляторы должны выполнить анализ указателя для дальнейшей оптимизации, что в значительной степени ограничено в C / C ++. Обычно это приводит к консервативным результатам анализа указателей и дает немного возможностей для оптимизации.