5

最も効率的なバリアントはどれですか?その理由は? それとも、同じコードに最適化されますか?

char inplace(int i) {
    // [some check if 0<=i<=2 here]
    return "azS"[i];
}

char infunc(int i) {
    const char s[] = "azS";
    // [some check if 0<=i<sizeof(s)/sizeof(s[0])-1 here]
    return s[i];
}

const char s[] = "azS";
char inglobals(int i) {
    // [some check if 0<=i<sizeof(s)/sizeof(s[0])-1 here]
    return s[i];
}

時期尚早の最適化がいかに悪であるかについて暴言を吐かないでください。

4

2 に答える 2

2

コードをコンパイルして逆アセンブルしました。inplaceinglobals同一です。.rodataこれは非常に直感的です。コンパイラは const 文字列をセクションに格納できます。

奇妙なことに、gcc はinfunc(以下を参照)に対して非常に多くのコードを生成sします。sasを定義すると、 and と同じコードstaticが生成されます。infuncinplaceinglobals

0000000000000010 :
  10: 48 83 ec 18 サブ $0x18、%rsp
  14: 48 63 ff movslq %edi,%rdi
  17: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
  1e: 00 00
  20: 48 89 44 24 08 mov %rax,0x8(%rsp)
  25: 31 c0 xor %eax,%eax
  27: c7 04 24 61 7a 53 00 movl $0x537a61,(%rsp)
  2e: 0f b6 04 3c movzbl (%rsp,%rdi,1),%eax
  32: 48 8b 54 24 08 mov 0x8(%rsp),%rdx
  37: 64 48 33 14 25 28 00 または %fs:0x28,%rdx
  3e: 00 00
  40: 75 05 年 47
  42: 48 83 c4 18 追加 $0x18、%rsp
  46: c3 retq   
  47: e8 00 00 00 00 callq 4c

編集

場所%fs:0x28は、GCC のスタック プロテクターに関連しています。無効にすると、次のコードが得られます。

0000000000000010 :
  10: 48 63 ff movslq %edi,%rdi
  13: c7 44 24 f0 61 7a 53 movl $0x537a61,-0x10(%rsp)
  1a:00
  1b: 0f b6 44 3c f0 movzbl -0x10(%rsp,%rdi,1),%eax
  20: c3 retq   

したがって、この場合、GCC は文字列をコードとインラインで格納し、実行中にスタックにコピーすることを選択しました。プロセッサのキャッシュはすでに文字列で満たされているため、メモリアクセスは発生しないため、これは非常に効率的であると私は主張します。

編集

要約すると、3 つのバージョンはすべて同等です。それでも、コンパイラの実装によっては、一方が他方よりも効率的であることが判明する場合があります。GCC の場合infunc、文字列は命令と共にフェッチされるため、短い文字列の方が効率的です。大きな文字列の場合は、inplaceorを使用しますinglobals

于 2012-08-31T09:58:41.740 に答える
1

コンパイラーは 1 と 3 で同じ結果を生成し、2 で同じ結果を生成する可能性があると思います (実際にデータをスタックにコピーしなくても済むことに気付いたかどうかによって少し異なります)。また、これがヘッダーやクラスのどこかにないことも想定しています。これにより、大きな違いが生じます(コードがそのように見えないことはわかっていますが、注意しているだけです)。

一般に、最適化によって別の方法が証明されない限り、宣言のスコープを最小化することにします (これは 3 を除外します)。1 と 2 の間では、文字列の内容を変更すると問題が発生する可能性が 1 の方がはるかに高くなります。

これは、生成されたコードに違いがない可能性が高いことを示唆していますが、オプション 2 は他の 2 つよりもはるかに優れています。

于 2012-08-31T09:56:23.260 に答える