使用以下方法之一访问数组元素时是否存在性能下降?
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/