memset的速度Vs直接赋值为零

LML*_*LML 3 c struct

请考虑下面的结构定义.

struct xyz {
  char a;
  void *ptr;
  uint16_t num1;
  uint32_t num2;
  uint64_t num3;
};
Run Code Online (Sandbox Code Playgroud)

我可以通过以下三种方式之一将此结构的实例初始化为零.

  1. 在申报时

    struct xyz instance = { 0 };
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在使用C-99功能声明它之后的某个时间.

    instance = (const struct xyz) { 0 };
    
    Run Code Online (Sandbox Code Playgroud)

3.memset (&instance, 0, sizeof (struct xyz));

典型的C结构可以由编译器添加一些填充以用于对齐目的.因此memset会将填充字节初始化为零.

我的问题是:

通常,上面的方法1或2的初始化会比方法3更快吗?保存多少CPU周期并不重要,我只是好奇1和2是否快于3.

Bas*_*tch 9

这是一个实施质量问题.

(顺便说一下,在纯理论中,一个实现可能有一个NULL指针,它不是一个全零位字;对于这种情况,你的§3的语义不同于§1或§2的语义;但在实践中,当今最常见的处理器有一个线性虚拟地址空间,并且它们的NULL指针是所有零位的字)

最近的GCC编译器(至少在通常的x86-64处理器上),启用了优化(例如gcc -O2)可能会生成相同(或非常相似)的机器代码(因为它memset被扩展为__builtin_memset特别编译并经常内联),因此使用memset是在实践中慢(甚至可能因为矢量化而变得更快,例如AVX机器指令)

您可以查看使用例如生成的汇编程序代码 gcc -S -fverbose-asm -O2 -march=native

(在某些情况下,特别是当struct xyz有数百个字段时,编译器甚至会memset为你的情况1和2 合成一个调用!)

通常,上面的方法1或2的初始化会比方法3更快吗?

在实践中,答案通常是否定的(因此更喜欢最易读的方法).如果您非常关心,请对代码进行基准测试.

(不要忘记,开发时间也要花钱;在很多情况下,你的人类时间比你可能赢得的几个CPU纳秒更值钱,而且通常不会

  • *如果你那么在意,请对你的代码进行基准测试。*这可能属于一个单独的答案,以巨大的红色闪烁字体。我会投票给它... ;-) (2认同)