为什么make_shared慢于shared_ptr <T>(new T)

时间:2019-11-26 06:56:25

标签: c++ performance shared-ptr make-shared

在每篇文章中都写道shared_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: %lf\n", ((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: %lf\n", ((double)end - start) / CLOCKS_PER_SEC); return 0; } 更有效,因为一个内存分配不是两个。但是我尝试下面的代码:

boost::shared_ptr

编译为:

  

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

并得到以下结果:

  

shared_ptr与新的:10.502945

     

make_shared:18.581738

make_shared相同:

  

shared_ptr与新的:10.778537

     

make_shared:18.962444

This question对于 LLVM的libc ++已损坏给出了答案,但是我使用GNU的libstdc ++。 那么,boost::shared_ptr为什么要慢一些?

P.S。使用-O3优化可以得到以下结果:

  

shared_ptr与新的:5.482464

     

make_shared:4.249722

get_results()相同。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

您看到的效果可能非常脆弱。在其他平台上的其他库,其他对象,其他向量大小等等下,您可能看不到它。

您发现了一种奇怪的情况,通常的建议碰巧会产生稍慢的结果。