What's the performance penalty of weak_ptr?

后端 未结 3 524
耶瑟儿~
耶瑟儿~ 2021-01-03 18:53

I\'m currently designing a object structure for a game, and the most natural organization in my case became a tree. Being a great fan of smart pointers I use shared_pt

3条回答
  •  醉梦人生
    2021-01-03 19:34

    Using/dereferencing a shared_ptr is almost like accessing raw ptr, locking a weak_ptr is a perf "heavy" operation compared to regular pointer access, because this code has to be "thread-aware" to work correctly in case if another thread triggers release of the object referenced by the pointer. At minimum, it has to perform some sort of interlocked/atomic operation that by definition is much slower than regular memory access.

    As usual, one way to see what's going on is to inspect generated code:

    #include 
    
    class Test
    {
    public:
        void test();
    };
    
    void callFuncShared(std::shared_ptr& ptr)
    {
        if (ptr)
            ptr->test();
    }
    
    void callFuncWeak(std::weak_ptr& ptr)
    {
        if (auto p = ptr.lock())
            p->test();
    }
    
    void callFuncRaw(Test* ptr)
    {
        if (ptr)
            ptr->test();
    }
    

    Accessing through shared_ptr and raw pointer is the same. Since shared_ptr was passed as a reference, we need to load referenced value, that's why the difference is only one extra load for shared_ptr version.

    callFuncShared:

    callFuncWeak:

    Calling through weak_ptr produces 10x more code and at best it has to go through locked compare-exchange, which by itself will take more than 10x CPU time than dereferencing raw or shared_ptr:

    Only if the shared counter isn't zero, only then it can load the pointer to actual object and use it (by calling the object, or creating a shared_ptr).

提交回复
热议问题