性能最佳的 C 和 C++ 编码风格

很多情况下,C 构造的性能成本不明显,有些甚至与直觉相反。

有如下一些情况:

  • 在任何可能的情况下,用 int 代替 charshort

    大多数情况下,charshort 数据项需要执行更多指令。 额外指令要花费时间,并且,除非是在大的数组中,通过使用较小的数据类型节省下来的所有空间比通过增加可执行程序的大小而产生的偏移量要大。

  • 如果一定要使用 char,在可能的情况下在前面加上 unsigned

    一个 signed char 变量在每次装入寄存器时比 unsigned char 多占用两条指令。

  • 尽可能使用局部(自动)变量而不是全局变量。

    全局变量比局部变量需要更多的指令来存取。 另外,在缺少信息的相反情况下,编译器假设所有全局变量可能已由某个子例程调用改变。 这个改变对优化起反作用,因为任何在子例程调用之后使用的全局变量值必须重新装入。

  • 当有必要存取全局变量(不与其他线程共享)时,将其值复制到局部变量中并且使用该副本。

    除非全局变量只存取一次,否则使用局部副本会更有效率。

  • 使用二进制代码而不是字符串来记录和测试各种情况。 字符串耗用数据和指令空间。 例如,序列:
    #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)
    . . .
  • 当必需使用字符串时,尽可能使用固定长度的字符串而不是无中止长度可变的字符串。

    mem*() 系列例程(如 memcpy())比对应的 str*() 例程(如 strcpy())快,因为 str*() 例程必须检查每个字节是否为 null,而 mem*() 例程则不用。