头号有新人 本人最近在优化一个原有项目时发现了一个很奇特的事情在此跟大家分享一下。这个项目由于某些历史原因使用了std::makeunique来创建一个拥有唯一使用权的对象指针。但是在经过性能剖析之后发现,这个函数耗费了相当长的时间,而memset函数调用居然占了大部分。这就奇怪了由于这个函数中压根没有任何对memset函数的调用,所以我猜测,就是在用std::makeunique创建对象时由编译器隐式生成的对memset函数的调用。由于它所创建的对象包含了一个16MB大小的数组,所以很明显,对那么大的数组使用memset也一定会有些耗时,更何况这个函数被调用得还算比较频繁。 于是我先做了一个小实验来验证这个问题。请看以下代码与结果: 这里为了方便观察结果,我定义了一个结构体S,在里面声明了包含4个字节的数组,然后显式指定它包含一个默认构造函数。在经过std::makeunique调用之后,果然其成员buffer的值都被清零了(见红色框框出部分)。而直接在栈上定义的对象s,其成员buffer没有被清零(见蓝色框框出部分)。 那如何避免成员buffer被自动清零呢?我于是稍作了修改,将默认构造函数改为显式定义一个不干任何事情的构造函数,然后各位可以看以下代码和结果: 我们可以看到,经过如此修改之后,通过std::makeunique构造的指针对象ptr中的buffer成员的值也不被自动清零了(红色框框出)。然后回到项目按此修改之后再看profile,memset消失了,帧率一下子提升了50