请考虑下面的结构定义。
struct xyz {
char a;
void *ptr;
uint16_t num1;
uint32_t num2;
uint64_t num3;
};
我可以通过以下三种方式之一将此结构的实例初始化为零。
在申报时
struct xyz instance = { 0 };
使用C-99功能声明后的某个时间。
instance = (const struct xyz) { 0 };
3。memset (&instance, 0, sizeof (struct xyz));
典型的C结构可能会由编译器添加一些填充以用于对齐目的。 因此memset会将填充字节初始化为零。
我的问题是:
通常,上述方法1或2的初始化是否比方法3快? 保存多少CPU周期并不重要,我只是好奇1& 2比3快或不快。
答案 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纳秒值更多,而且通常不会)