在替换共享指针的内容时优化对allocator的调用

问题描述 投票:1回答:2

考虑这个程序:

#include <memory>

struct T {
    T() {}
};

void do_something(std::shared_ptr<T> ptr) {
    // Do something with ptr; might or might not leave
    // other copies of ptr in other variables of the
    // program
}

int main() {
    std::shared_ptr<T> ptr = std::make_shared();
    do_something(ptr);
    // ptr might or might not be the only owner
    ptr = std::make_shared();
    return 0;
}

make_shared第二次执行时,ptr可能或可能有其他共享所有者,具体取决于do_something在运行时发生的情况。如果没有其他的,ptr会破坏和释放它以前拥有的对象,当或多或少同时分配和构造同一个新对象时。有没有办法避免分配和释放,并使用相同的区域来构建新对象? (这里的目标是优化对分配器的两次调用)

当然我接受新的T对象将在旧的对象被破坏之后被构造,而在上面的代码中则相反。所以我想像ptr.replace<U>(args)那样做以下事情:它减少了ptr的引用计数;如果计数变为零,则没有其他弱引用,Uptr内容的最派生类型,它会破坏拥有的对象,并在同一内存区域构造一个带有参数args的新对象,从而避免调用内存分配器。否则它的行为就像ptr = std::make_shared<U>(args)

无论如何使用当前的标准库执行此优化?

c++ smart-pointers
2个回答
2
投票

没有机制可以将weak_ptrs的数量计算到共享对象。您只能查询强计数(通过shared_ptr::use_count)。请注意,在多线程环境中,允许这是一个近似计数(即使用memory_order_relaxed加载)。

你确定这是性能瓶颈吗?


1
投票

考虑一下allocate_shared。它创建了一个带分配器的shared_ptr。可以在分配器中缓存已释放的shared_ptr的控制块,并立即在下一个allocate_shared调用中重用它,从而保存delete和new。

我怀疑它会有很大的不同。在多线程应用程序中,此分配器可以非常重要,以便快速和正确。

© www.soinside.com 2019 - 2024. All rights reserved.