“static const”、“#define”和“enum”在性能和内存使用方面的区别

Posted

技术标签:

【中文标题】“static const”、“#define”和“enum”在性能和内存使用方面的区别【英文标题】:Difference between “static const”, “#define”, and “enum” in performance and memory usage aspects 【发布时间】:2014-01-23 17:28:35 【问题描述】:

由于#define 语句的内联,可能存在任何问题。

我知道答案可能取决于编译器,那么假设 GCC。

about C 和 about C++ 已经有类似的问题,但更多的是关于使用方面的问题。

【问题讨论】:

请举例说明您所询问的值类型。既然你提到enum,我猜是整数数字常量? @πάνταῥεῖ 我问的是一般情况 - 关于所有可能类型的常量:数字、字符串文字、数组...... 所以要点是不要使用#define 在“现代”C++ 中定义整数常量。如果它确实是一个数字,请使用 static const。如果它确实是一个可枚举的值,请使用 enum。不要担心性能和内存使用:相信你的编译器,除非它真的非常关键,在这种情况下相信你的编译器,但要检查以确保。 【参考方案1】:

在给定基本优化的情况下,编译器会以同样的方式对待它们。 检查起来相当容易 - 考虑以下 c 代码:

#define a 1
static const int b = 2;
typedef enum FOUR = 4 enum_t;

int main() 

    enum_t c = FOUR;

    printf("%d\n",a);
    printf("%d\n",b);
    printf("%d\n",c);

    return 0;

用 gcc -O3 编译:

0000000000400410 <main>:
  400410:       48 83 ec 08             sub    $0x8,%rsp
  400414:       be 01 00 00 00          mov    $0x1,%esi
  400419:       bf 2c 06 40 00          mov    $0x40062c,%edi
  40041e:       31 c0                   xor    %eax,%eax
  400420:       e8 cb ff ff ff          callq  4003f0 <printf@plt>
  400425:       be 02 00 00 00          mov    $0x2,%esi
  40042a:       bf 2c 06 40 00          mov    $0x40062c,%edi
  40042f:       31 c0                   xor    %eax,%eax
  400431:       e8 ba ff ff ff          callq  4003f0 <printf@plt>
  400436:       be 04 00 00 00          mov    $0x4,%esi
  40043b:       bf 2c 06 40 00          mov    $0x40062c,%edi
  400440:       31 c0                   xor    %eax,%eax
  400442:       e8 a9 ff ff ff          callq  4003f0 <printf@plt>

完全相同的汇编代码,因此 - 完全相同的性能和内存使用。

编辑:正如 Damon 在 cmets 中所说,可能存在一些极端情况,例如复杂的非文字,但这有点超出了问题的范围。

【讨论】:

有趣的大写选择:一个小写的宏和一个全部大写的枚举:) 感谢您的回答,但如果这些常量有多种用途,程序集表示不会改变吗? @user3075942:会有更多的代码,但是如果你只使用,编译器会在调用的地方替换它。为什么变量的 1 次或 100 次使用会发生变化? 至于字符串文字 - 你会发现将这种情况与enum 进行比较会更复杂,但这并不会改变基本事实 - 编译器将所有这些都视为值,并且可以优化您可能认为他们持有的任何类型的临时存储。因此,它处理一种与另一种不同的常量是没有意义的(更不用说编译器甚至看不到#define 不幸的是,对于 许多 非整数文字情况,“相同”不是真的。例如,您可能期望 static const&amp; 也可以进行微不足道的优化,但事实并非如此。例如。 struct fooint bar;; static const&amp; bar_ref = foo.bar; 的开销肯定比 #define bar_ref foo.bar 多。 (是的,确实有需要这种可憎的情况。不要问。)【参考方案2】:

当用作常量表达式时,性能没有差异。如果用作左值,static const 将需要定义(内存)和访问(cpu)。

【讨论】:

以上是关于“static const”、“#define”和“enum”在性能和内存使用方面的区别的主要内容,如果未能解决你的问题,请参考以下文章

OC 中static、const理解

const和static const的区别(未整理)

C++面向对象-static、const

C++ const和static const的区别

static const readonly

static, const