最高のパフォーマンスを得るための C および C++ コーディング・スタイル

多くの場合、C 構成のパフォーマンス・コストは明らかでなく、ときには直観に反したものでさえあります。

これらの状態の幾つかを、以下に示します。

  • 可能な場合は必ず、char または short の代わりに int を使用してください。

    ほとんどの場合、char および short データ項目を使用するには、 より多くの命令を操作する必要があります。 余分な命令には時間がかかる上、大きな配列の場合を除いて、より小さいデータ型を使用することによってスペースを節約するほうが、実行可能プログラムのサイズを増加して補正することより優っています。

  • char を使用する必要がある場合は、可能であれば、 それを unsigned にしてください。

    signed char の場合は、この変数がレジスターにロードされるつど、unsigned char より 2 つ余分に命令が必要になります。

  • 可能な場合は必ず、グローバル変数ではなく、ローカル (自動) 変数を使用してください。

    グローバル変数は、アクセスするのにローカル変数より多くの命令を必要とします。 また、逆に情報が存在しない場合、コンパイラーは、グローバル変数がサブルーチン呼び出しによって変更されていると想定します。 サブルーチン呼び出しの後でグローバル変数の値を使用する場合は、 その値を再ロードする必要があるので、この変更は最適化には逆効果です。

  • グローバル変数 (他のスレッドと共用されていない) にアクセスする必要がある場合は、 その値をローカル変数にコピーして、そのコピーを使用してください。

    グローバル変数へのアクセスが 1 回のみでない限り、ローカル・コピーを使用した方が効率的です。

  • 状態を記録し、テストする際は、文字列ではなくバイナリー・コードを使用してください。 文字列は、データと命令スペースの両方を消費します。 例えば、次のシーケンス、
    #define situation_1 1
    #define situation_2 2
    #define situation_3 3
    int situation_val;
    
    situation_val = situation_2;
    . . .
    if (situation_val == situation_1)
    . . .

    は、次のシーケンスよりはるかに効率的です。

    char situation_val[20];
    
    strcpy(situation_val,"situation_2");
    . . .
    if ((strcmp(situation_val,"situation_1"))==0)
    . . .
  • 文字列が必要なときは、可能な場合は必ず、null 終了の可変長文字列ではなく、 固定長文字列を使用してください。

    memcpy() など、ルーチンの mem*() ファミリーは、strcpy() などの対応する str*() ルーチンより高速です。それは、str*() ルーチンは null があるかどうか各バイトを調べる必要があり、mem*() ルーチンにはその必要がないからです。