【问题标题】:C++ smart pointer performance and difference with a simple wrapped pointerC++ 智能指针性能和与简单包装指针的区别
【发布时间】:2017-09-04 16:30:28
【问题描述】:

我遇到了有人在 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");
}

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

【问题讨论】:

  • "在调试模式下"你永远不应该永远在调试模式下衡量和推理性能。
  • 内存分配成本将使任何分配成本相形见绌。此测试无效。
  • shared_ptr 进行线程安全引用计数,而其他指针不这样做,因此预计会更慢。
  • 在我看来,速度并不是make_ 函数的重点。安全是。 make_ 比普通的 new 和存储更好地处理失败案例。
  • 如果我们从问题中删除所有不相关的数据(提到未优化的构建及其性能),还剩下什么?

标签: c++ shared-ptr smart-pointers unique-ptr


【解决方案1】:

据我所知,实际问题是:

我想知道,如果我使用自己的智能指针,unique_pointer 是否会做一些我会丢失的特殊操作?它似乎很重,至少在调试模式下它似乎做了很多。

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

尽管unique_ptr 是最简单的拥有智能指针,但它仍然做了很多你的琐碎包装器没有做的事情:

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

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

只需使用unique_ptr,在关闭优化的情况下自行滚动以获得更好的性能并不是一个好理由。

【讨论】:

  • @Zebrafish Np,如果您觉得它完全回答了您的问题,您可以将其标记为已接受,以便理解问题已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
相关资源
最近更新 更多