局部变量与阵列访问

jsj*_*jsj 1 c c++ optimization performance pointers

哪一项计算效率更高,为什么?

A)重复阵列访问:

for(i=0; i<numbers.length; i++) {
    result[i] = numbers[i] * numbers[i] * numbers[i];
}
Run Code Online (Sandbox Code Playgroud)

B)设置局部变量:

for(i=0; i<numbers.length; i++) {
    int n = numbers[i];
    result[i] = n * n * n;
}
Run Code Online (Sandbox Code Playgroud)

是不是必须计算重复的数组访问版本(使用指针算术),使第一个选项变慢,因为它正在这样做?:

for(i=0; i<numbers.length; i++) {
    result[i] = *(numbers + i) * *(numbers + i) * *(numbers + i);
}
Run Code Online (Sandbox Code Playgroud)

Fre*_*abe 10

任何足够复杂的编译器都会为所有三个解决方案生成相同的代码 我把你的三个版本变成了一个小的C程序(带有一个小调整,我改变了numbers.length对宏调用的访问,它给出了一个数组的长度):

#include <stddef.h>

size_t i;
static const int numbers[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9 };

#define ARRAYLEN(x) (sizeof((x)) / sizeof(*(x)))
static int result[ARRAYLEN(numbers)];

void versionA(void)
{
    for(i=0; i<ARRAYLEN(numbers); i++) {
        result[i] = numbers[i] * numbers[i] * numbers[i];
    }
}

void versionB(void)
{
    for(i=0; i<ARRAYLEN(numbers); i++) {
        int n = numbers[i];
        result[i] = n * n * n;
    }
}

void versionC(void)
{
    for(i=0; i<ARRAYLEN(numbers); i++) {
            result[i] = *(numbers + i) * *(numbers + i) * *(numbers + i);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我使用Visual Studio 2012使用优化(和调试符号,用于更漂亮的反汇编)编译它:

C:\Temp>cl /Zi /O2 /Wall /c so19244189.c
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.50727.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

so19244189.c
Run Code Online (Sandbox Code Playgroud)

最后,这是反汇编:

C:\Temp>dumpbin /disasm so19244189.obj

[..]

_versionA:
  00000000: 33 C0              xor         eax,eax
  00000002: 8B 0C 85 00 00 00  mov         ecx,dword ptr _numbers[eax*4]
            00
  00000009: 8B D1              mov         edx,ecx
  0000000B: 0F AF D1           imul        edx,ecx
  0000000E: 0F AF D1           imul        edx,ecx
  00000011: 89 14 85 00 00 00  mov         dword ptr _result[eax*4],edx
            00
  00000018: 40                 inc         eax
  00000019: 83 F8 09           cmp         eax,9
  0000001C: 72 E4              jb          00000002
  0000001E: A3 00 00 00 00     mov         dword ptr [_i],eax
  00000023: C3                 ret

_versionB:
  00000000: 33 C0              xor         eax,eax
  00000002: 8B 0C 85 00 00 00  mov         ecx,dword ptr _numbers[eax*4]
            00
  00000009: 8B D1              mov         edx,ecx
  0000000B: 0F AF D1           imul        edx,ecx
  0000000E: 0F AF D1           imul        edx,ecx
  00000011: 89 14 85 00 00 00  mov         dword ptr _result[eax*4],edx
            00
  00000018: 40                 inc         eax
  00000019: 83 F8 09           cmp         eax,9
  0000001C: 72 E4              jb          00000002
  0000001E: A3 00 00 00 00     mov         dword ptr [_i],eax
  00000023: C3                 ret

_versionC:
  00000000: 33 C0              xor         eax,eax
  00000002: 8B 0C 85 00 00 00  mov         ecx,dword ptr _numbers[eax*4]
            00
  00000009: 8B D1              mov         edx,ecx
  0000000B: 0F AF D1           imul        edx,ecx
  0000000E: 0F AF D1           imul        edx,ecx
  00000011: 89 14 85 00 00 00  mov         dword ptr _result[eax*4],edx
            00
  00000018: 40                 inc         eax
  00000019: 83 F8 09           cmp         eax,9
  0000001C: 72 E4              jb          00000002
  0000001E: A3 00 00 00 00     mov         dword ptr [_i],eax
  00000023: C3                 ret
Run Code Online (Sandbox Code Playgroud)

注意在所有情况下组件是如何完全相同的.所以对你的问题的正确答案

哪一项计算效率更高,为什么?

这个编译器是:mu.您的问题无法回答,因为它基于不正确的假设.答案都没有比其他答案更快.