You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中unique_ptr性能优于原始指针?基准测试异常结果求解

问题原因分析
  • 最核心的问题是基准测试没有添加防止编译器过度优化的标记:你测试中的两个指针变量都是局部变量,没有任何后续使用,编译器在高优化等级(比如O2、O3)下会尝试消除无副作用的代码。标准库的std::unique_ptr实现是编译器熟知的模板逻辑,更容易被判定为无副作用直接消除整个new+构造+析构+delete流程,而手动实现的raw指针+自定义deleter的逻辑,编译器可能没有完全消除,最终出现raw指针测试耗时更长的错误结果。你需要使用Google Benchmark提供的benchmark::DoNotOptimize标记指针,防止编译器将相关操作优化掉。
  • 测试对象太小,开销被堆分配淹没:你测试中分配的是仅4字节的int类型,new/delete的堆操作开销远大于指针本身的管理开销,测试实际统计的是堆分配速度,而非两种指针的操作差异。
  • 无状态自定义deleter的优化差异:你定义的deleter是空类,没有任何成员变量,std::unique_ptr会触发空基类优化,不需要额外存储deleter对象,构造、析构过程的所有逻辑都会在编译期展开,和直接调用delete没有任何运行时差异,理论上两段代码的开销完全一致。
修正后的测试代码示例
struct deleter 
{
    template<typename T>
    void operator()(T* ptr) 
    {
        delete ptr;
    }
};

void BM_rawPtr(benchmark::State& state)
{
    deleter d;
    for (auto _ : state)
    {
        int* p = new int(0);
        benchmark::DoNotOptimize(p); // 防止p被优化消除
        d(p);
    }
    state.SetItemsProcessed(state.iterations());
}


void BM_uniquePtr(benchmark::State& state)
{
    deleter d;
    for (auto _ : state)
    {
        std::unique_ptr<int, deleter> ptr(new int(0), d);
        benchmark::DoNotOptimize(ptr); // 防止ptr被优化消除
    }
    state.SetItemsProcessed(state.iterations());
}

BENCHMARK(BM_rawPtr);
BENCHMARK(BM_uniquePtr);
BENCHMARK_MAIN();

修正后在同等级别优化下重新测试,两段代码的耗时会基本一致,符合unique_ptr是零开销抽象的特性,不会出现比raw指针更快的异常结果。

内容的提问来源于stack exchange,提问作者Eduard Rostomyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:39:01