为什么make_shared比shared_ptr<T>(新T)慢

Why make_shared slower than shared_ptr<T>( new T)

本文关键字:shared gt lt make ptr 为什么      更新时间:2023-10-16

在每篇文章中都写到make_sharedshared_ptr<T>(new T)更有效率,因为一个内存分配而不是两个内存分配。但我尝试以下代码:

#include <cstdio>
#include <ctime>
#include <memory>
#include <vector>
static const size_t N = 1L << 25;
int main(void) {
clock_t start = clock();
for ( size_t rcx = 0; rcx < N; rcx++ ) {
auto tmp = std::shared_ptr<std::vector<size_t>>( new std::vector<size_t>( 1024 ) );
}
clock_t end = clock();
printf("shared_ptr with new: %lfn", ((double)end - start) / CLOCKS_PER_SEC);
start = clock();
for ( size_t rcx = 0; rcx < N; rcx++ ) {
auto tmp = std::make_shared<std::vector<size_t>>( 1024 );
}
end = clock();
printf("make_shared: %lfn", ((double)end - start) / CLOCKS_PER_SEC);
return 0;
}

编译方式:

g++ --std=c++14 -O2 test.cpp -o test

并得到了这个结果:

shared_ptr新:10.502945

make_shared: 18.581738

boost::shared_ptr相同:

shared_ptr新:10.778537

make_shared: 18.962444

这个问题有关于LLVM的libc++的答案是坏的,但我使用GNU的libstdc++。 那么,为什么make_shared慢呢?

附言使用 -O3 优化得到这个结果:

shared_ptr新品:5.482464

make_shared: 4.249722

boost::shared_ptr也一样.

在一台计算机上运行程序并测量执行时间不会提供有关程序性能的任何一般信息,而只会在实际条件下在您的设备上提供。 例如,依赖于您的操作系统、编译器、设备上运行的其他程序、库版本甚至您的用户名。
由于您的程序确实访问主内存,因此在您的特殊情况下,程序的结构可能会使访问内存更"快速"。但当然,如果您终止或启动其他软件,更改用户或操作系统重构主内存,则"性能"看起来完全不同。
因此,如果您想要可靠的数据,您应该至少在不同的设备和不同的条件下运行该程序。但我建议您看看"分析器"软件。

在您的平台上,std::vector的分配器中可能进行了优化。请记住,您实际上在这里有三个可能的分配,而不是两个。有共享控件对象、矢量对象本身以及初始 1,024 个size_t对象的空间。

通过使用make_shared,您将失去利用该优化的机会,因为共享控制结构和向量是同时创建的。这是一个不寻常的边缘情况,您可能会发现在其他对象和其他使用模式中看不到这一点。

你看到的效果可能非常脆弱。在其他库、其他平台、其他对象、其他矢量大小等中,您可能不会看到它。

你发现了一个奇怪的边缘情况,通常的建议碰巧产生稍微慢一点的结果。