【发布时间】:2021-10-28 14:16:09
【问题描述】:
我在这里尝试了基准测试并发现了奇怪的结果。
显然创建和删除原始指针比创建unique_ptr 慢(当然根据我的测量),这怎么可能?
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);
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);
}
state.SetItemsProcessed(state.iterations());
}
BENCHMARK(BM_rawPtr);
BENCHMARK(BM_uniquePtr);
BENCHMARK_MAIN();
这给了我奇怪的结果:
我不想说“unique_ptr 比原始指针快”之类的废话。
显然我在这里漏掉了一些要点,这是否对任何人敲响了警钟?
提前致谢。
【问题讨论】:
-
可以尝试一个空循环来了解完全优化的输出时序是什么样的
-
您检查的是否相同,但顺序相反(unique_ptr 在前)?可能是来自操作系统的单一分配的覆盖,然后所有剩余的
new调用都使用该内存。 -
您需要检查生成的代码以确保像
int* p = new int(0); d(p);这样的行没有被优化掉,因为它们没有明显的效果。std::unique_ptr<int, deleter> ptr(new int(0), d);也是优化移除的候选对象。 -
编译(有变化见minimal reproducible example)为没有clang和gcc-live的代码-godbolt.org/z/4WGMcbhMv基准测试很难。
-
尝试使用
benchmark::DoNotOptimize(p);和benchmark::DoNotOptimize(ptr);来防止编译器优化掉指针。我尝试使用quickbench.com 对您的代码进行基准测试。很明显,您可以看到,在没有优化的情况下,原始指针的执行速度更快。然而,通过优化,两者是等价的。 (假设操作系统没有内存分配开销。)
标签: c++ c++11 pointers benchmarking unique-ptr