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

C++ smart pointer performance and difference with a simple wrapped pointer

我遇到了有人对 C++ 智能指针所做的测试,我想知道一些事情。首先,我听说 make_shared 和 make_unique 比共享指针或唯一指针的正常构造更快。但是我的结果和创建测试的人的结果表明 make_unique 和 make_shared 稍微慢一点(可能没什么大不了的)。但我也想知道,在调试模式下,对我来说 unique_pointer 比普通指针慢大约 3 倍,而且确实也比我自己简单地将指针包装在 class 中慢得多。在发布模式下,原始指针,我包装的 class 和 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");
}

我找到这个的 link http://www.modernescpp.com/index.php/memory-and-performance-overhead-of-smart-pointer

据我所知,实际问题是:

I was wondering, does the unique_pointer do anything special that I would lose if I used my own smart pointer? It seems to be rather heavy, well at least in debug mode it seems to be doing a lot.

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

尽管 unique_ptr 是最简单的拥有智能指针的写法,它仍然可以做很多普通包装器做不到的事情:

  • 它允许自定义删除器,同时通过 Empty Base Class 优化
  • 确保无状态自定义删除器不使用额外的 space
  • 它能正确处理移动和复制
  • 它能正确处理各种转换;例如 unique_ptr<Derived> 将隐式转换为 unique_ptr<Base>
  • 常量正确

尽管大多数体面的 C++ 程序员都可以实现体面的 unique_ptr,但我认为大多数人都无法实现完全正确的。那些极端情况会伤害你。

只需使用 unique_ptr,为了获得更好的性能而关闭优化并不是一个好的理由。