C++智能指针的性能和与简单包装指针的区别

Zeb*_*ish 2 c++ smart-pointers shared-ptr unique-ptr

我遇到过有人在C++智能指针上做过的测试,我想知道一些事情.首先,我听说make_shared和make_unique比正常构建共享或唯一指针要快.但是我的结果和创建测试的人的结果显示make_unique和make_shared略慢(可能没什么大不了的).但我也想知道,在调试模式下,对于我来说,unique_pointer比普通指针慢大约3倍,而且实际上也比我自己在类中简单地包装指针慢得多.在发布模式下,原始指针,我的包装类和unique_ptrs大致相同.我想知道,如果我使用自己的智能指针,unique_pointer会做什么特别的事情吗?它似乎相当沉重,至少在调试模式下似乎做了很多.测试如下:

#include <chrono>
#include <iostream>
#include <memory>

static const long long numInt = 100000000;

template <typename T>
struct SmartPointer
{
    SmartPointer(T* pointee) : ptr(pointee) {}
    T* ptr;
    ~SmartPointer() { delete ptr; }
};

int main() {

    auto start = std::chrono::system_clock::now();

    for (long long i = 0; i < numInt; ++i) {
        //int* tmp(new int(i));
        //delete tmp;
        //SmartPointer<int> tmp(new int(i));
        //std::shared_ptr<int> tmp(new int(i));
        //std::shared_ptr<int> tmp(std::make_shared<int>(i));
        //std::unique_ptr<int> tmp(new int(i));
        //std::unique_ptr<int> tmp(std::make_unique<int>(i));
    }

    std::chrono::duration<double> dur = std::chrono::system_clock::now() - start;
    std::cout << "time native: " << dur.count() << " seconds" << std::endl;

    system("pause");
}
Run Code Online (Sandbox Code Playgroud)

我发现这个链接是在 http://www.modernescpp.com/index.php/memory-and-performance-overhead-of-smart-pointer

Nir*_*man 9

我能说的最好,实际的问题是:

我想知道,如果我使用自己的智能指针,unique_pointer会做什么特别的事情吗?它似乎相当沉重,至少在调试模式下似乎做了很多.

有可能unique_ptr可能有更多的微不足道的函数调用或类似的东西,它们没有完全内联,导致调试模式下的性能更差.但是,正如您自己所说,在重要的情况下,启用优化后的性能是相同的.

即使unique_ptr是最简单的拥有写入的智能指针,它仍然会做很多你的琐碎包装器没有的东西:

  • 它允许自定义删除程序,同时确保无状态自定义删除程序不通过空基类优化使用额外空间
  • 它正确处理移动和复制
  • 它正确处理各种转换; 例如unique_ptr<Derived>将隐式转换为unique_ptr<Base>
  • 这是正确的

虽然大多数体面的C++程序员都可以实现一个体面的unique_ptr,但我认为大多数人都不能实现一个完全正确的程序.那些边缘情况会伤害你.

只需使用unique_ptr,滚动自己以获得更好的性能并优化关闭并不是一个好理由.