c++ - 为了方便起见,本地指针/引用的性能

标签 c++

使用以下方法之一访问数组元素时是否存在性能下降?

int someRandomArrayWithLongName[] = {0, 1, 2, 3, 4};

// case (1): access with alias reference
int &elem = someRandomArrayWithLongName[1];
while (!exit)
{
   ++elem;
}

// case (2): pointer access
int *elem = &someRandomArrayWithLongName[1];
while (!exit)
{
   ++(*elem);
}

// default case (3): conventional element access
while (!exit)
{
   ++someRandomArrayWithLongName[1];
}

特别是,编译器会识别别名并发挥其作用来防止不必要的内存分配(情况 1 和 2)吗?或者只使用案例 3 更好?

编辑:我使用了http://gcc.godbolt.org/正如评论中所建议的。结果这三种情况产生了完全相同的汇编代码( source ):

test1():
    movzbl  exit(%rip), %eax
    testb   %al, %al
    jne .L1
    movl    someRandomArrayWithLongName+4(%rip), %eax
    addl    $1, %eax
.L3:
    movzbl  exit(%rip), %edx
    movl    %eax, %ecx
    addl    $1, %eax
    testb   %dl, %dl
    je  .L3
    movl    %ecx, someRandomArrayWithLongName+4(%rip)
.L1:
    rep ret
test2():
    movzbl  exit(%rip), %eax
    testb   %al, %al
    jne .L8
    movl    someRandomArrayWithLongName+4(%rip), %eax
    addl    $1, %eax
.L10:
    movzbl  exit(%rip), %edx
    movl    %eax, %ecx
    addl    $1, %eax
    testb   %dl, %dl
    je  .L10
    movl    %ecx, someRandomArrayWithLongName+4(%rip)
.L8:
    rep ret
test3():
    movzbl  exit(%rip), %eax
    testb   %al, %al
    jne .L14
    movl    someRandomArrayWithLongName+4(%rip), %eax
    addl    $1, %eax
.L16:
    movzbl  exit(%rip), %edx
    movl    %eax, %ecx
    addl    $1, %eax
    testb   %dl, %dl
    je  .L16
    movl    %ecx, someRandomArrayWithLongName+4(%rip)
.L14:
    rep ret
exit:
    .zero   1

最佳答案

您担心的“不必要的内存分配”在最坏的情况下只涉及很小的堆栈空间,并且实际上不需要额外的时间,因此无需担心。

也就是说,任何有值(value)的现代编译器很可能会在优化版本中为所有三个编译器生成相同的代码。
在实践中,使用您认为最可读(并且最不容易出错)的那个,如果结果太慢则重写。

为了提高性能,您应该努力避免访问内存,方法是尽可能将修改保持在本地,以便它们可以在寄存器中执行,如下所示:

int increment = 0;
while (!exit)
{
   ++increment;
}
someRandomArrayWithLongName[1] += increment;

关于c++ - 为了方便起见,本地指针/引用的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25784669/

相关文章:

C++ 无法从 const int* 转换为 const_iterator

c++ - CX0030 : Error: Expression cannot be evaluated

c++ - 模板化转换构造函数无法访问 protected 数据成员

c++ - 打开不存在的文件时如何使 ofstream 构造函数失败?

c++ - 如何在不格式化的情况下写入 std::ostream?

c++ - 为什么 std::optional::operator=(U&&) 要求 U 是非标量类型?

c++ - Qt下opencv崩溃无报错

c++ - 解析复合语法时内部 Boost::Spirit 代码段错误

c++ - 默认参数问题(c++)

c++ - 我是否必须在类主体之外定义纯虚拟析构函数?