一个空的别名shared_ptr是一个很好的替代无操作删除shared_ptr吗?
Is an empty aliasing shared_ptr a good alternative to a no-op deleting shared_ptr?
有时我需要具有无操作删除器的shared_ptr
实例,因为API期望它想要存储有限时间的shared_ptr
实例,但我得到了一个原始指针,我不允许拥有比我运行的时间更长的时间。
对于这种情况,我一直在使用无操作删除器,如[](const void *){}
,但今天我发现还有另一种选择,使用(或滥用?)shared_ptr
的混叠构造函数:
void f(ExpectedClass *ec) {
std::shared_ptr<ExpectedClass> p(std::shared_ptr<void>(), ec);
assert(p.use_count() == 0 && p.get() != nullptr);
apiCall(p);
}
我的问题是,什么是更好的方法,为什么?绩效期望是一样的吗?对于无操作的删除器,我希望为删除器和引用计数的存储支付一些成本,而在使用带有空shared_ptr
的别名构造函数时,似乎不会出现这种情况。
关于性能,下面的基准测试显示了不稳定的数字:
#include <chrono>
#include <iostream>
#include <limits>
#include <memory>
template <typename... Args>
auto test(Args&&... args) {
using clock = std::chrono::high_resolution_clock;
auto best = clock::duration::max();
for (int outer = 1; outer < 10000; ++outer) {
auto now = clock::now();
for (int inner = 1; inner < 20000; ++inner)
std::shared_ptr<int> sh(std::forward<Args>(args)...);
auto time = clock::now()-now;
if (time < best) {
best = time;
outer = 1;
}
}
return best.count();
}
int main()
{
int j;
std::cout << "With aliasing ctor: " << test(std::shared_ptr<void>(), &j) << 'n'
<< "With empty deleter: " << test(&j, [] (auto) {});
}
我的机器上clang++ -march=native -O2
的输出:
With aliasing ctor: 11812
With empty deleter: 651502
具有相同选项的GCC给出了更大的比率,5921:465794。
与-stdlib=libc++
的Clang产生了惊人的12:613175。
快速工作台
#include <memory>
static void aliasConstructor(benchmark::State& state) {
for (auto _ : state) {
int j = 0;
std::shared_ptr<int> ptr(std::shared_ptr<void>(), &j);
benchmark::DoNotOptimize(ptr);
}
}
BENCHMARK(aliasConstructor);
static void NoOpDestructor(benchmark::State& state) {
for (auto _ : state) {
int j = 0;
std::shared_ptr<int> ptr(&j, [](int*){});
benchmark::DoNotOptimize(ptr);
}
}
BENCHMARK(NoOpDestructor);
为
- gcc 10.2的比率为1/30
- clang 11libc++的比值为1/25
所以别名构造函数胜出
相关文章:
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理