在 C 语言中(或者一般情况下),使用算术获取值或从数组/变量调用它更快吗?
例如,如果我有
int myarray[7] = {16};
int mysixteen = 16;
然后我可以通过多种不同的方式得到 16
myarray[#]
mysixteen
16
1 << 4
10 + 6
从逻辑上讲,16 是最快的,但对于一组数字来说,这并不总是方便或合理。这可能相关的一个例子是预计算表。假设您需要 64 位的位掩码,您可以填充一个数组
for (int i = 0; i < 64; ++i) {
mask[i] = 1 << i;
}
并在将来调用该数组,或者创建一个宏
#define mask(b) (1 << b)
并称之为。
最佳答案
一般来说,任何一个
- 16
- 1 << 4
- 10 + 6
将产生文字16
,因为编译器肯定会实现名为 constant folding 的优化。 .
性能
- 我的十六岁
- myarray[n]
可能较低,具体取决于这些变量值的存储位置。在内存中?如果是,该内存是否位于任何 CPU 缓存中?或者它存储在CPU寄存器之一中?没有明确的答案。
一般来说,对于特定程序,您始终可以看到编译器为您提供的内容 - 但请注意,这可能会根据周围的代码和优化标志而发生很大变化。
要亲自尝试一下,请考虑这个小程序:
int f() { return 16; }
int g() { return 1 << 4; }
int h() { return 10 + 6; }
int i() {
int myarray[7] = { 16 };
return myarray[3];
}
int j() {
int mysixteen = 16;
return mysixteen;
}
如果我使用 gcc 4.7.2 编译它,然后检查反汇编,例如
$ gcc -c so19802742.c -o so19802742.o
$ objdump --disassemble so19802742.o
我明白了:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 10 00 00 00 mov $0x10,%eax
9: 5d pop %rbp
a: c3 retq
000000000000000b <g>:
b: 55 push %rbp
c: 48 89 e5 mov %rsp,%rbp
f: b8 10 00 00 00 mov $0x10,%eax
14: 5d pop %rbp
15: c3 retq
0000000000000016 <h>:
16: 55 push %rbp
17: 48 89 e5 mov %rsp,%rbp
1a: b8 10 00 00 00 mov $0x10,%eax
1f: 5d pop %rbp
20: c3 retq
0000000000000021 <i>:
21: 55 push %rbp
22: 48 89 e5 mov %rsp,%rbp
25: 48 c7 45 e0 00 00 00 movq $0x0,-0x20(%rbp)
2c: 00
2d: 48 c7 45 e8 00 00 00 movq $0x0,-0x18(%rbp)
34: 00
35: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
3c: 00
3d: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
44: c7 45 e0 10 00 00 00 movl $0x10,-0x20(%rbp)
4b: 8b 45 ec mov -0x14(%rbp),%eax
4e: 5d pop %rbp
4f: c3 retq
0000000000000050 <j>:
50: 55 push %rbp
51: 48 89 e5 mov %rsp,%rbp
54: c7 45 fc 10 00 00 00 movl $0x10,-0x4(%rbp)
5b: 8b 45 fc mov -0x4(%rbp),%eax
5e: 5d pop %rbp
5f: c3 retq
请注意,由于常量折叠,f
、g
和 h
会产生完全相同的机器代码。 i
中的数组访问会导致最多的机器代码(但不一定是最慢的!),而 j
则介于两者之间。
但是,这根本没有任何更复杂的代码优化!使用例如编译时生成的代码-O2
可能完全不同,因为编译器注意到对这五个函数中任何一个的调用都相当于仅使用常量16
!
关于c - 使用算术比存储变量更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19802742/