memset的速度Vs直接赋值为零

时间:2017-09-13 05:56:10

标签: c struct

请考虑下面的结构定义。

struct xyz {
  char a;
  void *ptr;
  uint16_t num1;
  uint32_t num2;
  uint64_t num3;
};

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

  1. 在申报时

    struct xyz instance = { 0 };
    
  2. 使用C-99功能声明后的某个时间。

    instance = (const struct xyz) { 0 };
    
  3. 3。memset (&instance, 0, sizeof (struct xyz));

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

    我的问题是:

    通常,上述方法1或2的初始化是否比方法3快? 保存多少CPU周期并不重要,我只是好奇1& 2比3快或不快。

1 个答案:

答案 0 :(得分: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有数百个字段时,编译器甚至会为你的案例1和2合成memset的调用!)

  

通常,上述方法1或2的初始化是否比方法3快?

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

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