一般に、いずれか
コンパイラは定数折りたたみ16
と呼ばれる最適化を確実に実装するため、結果はリテラルになります。
の性能
これらの変数の値が格納されている場所によっては、おそらく低くなります。記憶に?もしそうなら、メモリはいずれかの CPU キャッシュにありますか? それとも、CPUレジスタの1つに格納されていますか? 決定的な答えはありません。
一般に、特定のプログラムについては、コンパイラが提供するものをいつでも確認できますが、これは周囲のコードと最適化フラグによって大きく変わる可能性があることに注意してください。
自分で試してみるには、次の小さなプログラムを検討してください。
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
は限りません!) を引き起こし、その中間のようなものです。
ただし、これには複雑なコードの最適化はまったくありません。eg でコンパイルしたときに生成されるコードは、まったく-O2
異なる場合があります。これは、コンパイラが、5 つの関数のいずれかの呼び出しが定数!16