Is make_shared really more efficient than new?

前端 未结 4 1662
花落未央
花落未央 2020-12-02 08:56

I was experimenting with shared_ptr and make_shared from C++11 and programmed a little toy example to see what is actually happening when calling <

4条回答
  •  广开言路
    2020-12-02 09:55

    So one thing to keep in mind is your optimization settings. Measuring performance, particularly with regard to c++ is meaningless without optimizations enabled. I don't know if you did in fact compile with optimizations, so I thought it was worth mentioning.

    That said, what you are measuring with this test is not a way that make_shared is more efficient. Simply put, you are measuring the wrong thing :-P.

    Here's the deal. Normally, when you create shared pointer, it has at least 2 data members (possibly more). One for the pointer, and one for the reference count. This reference count is allocated on the heap (so that it can be shared among shared_ptr with different lifetimes...that's the point after all!)

    So if you are creating an object with something like std::shared_ptr p2(new Object("foo")); There are at least 2 calls to new. One for Object and one for the reference count object.

    make_shared has the option (i'm not sure it has to), to do a single new which is big enough to hold the object pointed to and the reference count in the same contiguous block. Effectively allocating an object that looks something like this (illustrative, not literally what it is).

    struct T {
        int reference_count;
        Object object;
    };
    

    Since the reference count and the object's lifetimes are tied together (it doesn't make sense for one to live longer than the other). This whole block can be deleted at the same time as well.

    So the efficiency is in allocations, not in copying (which I suspect had to do with optimization more than anything else).

    To be clear, this is what boost has to say on about make_shared

    http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html

    Besides convenience and style, such a function is also exception safe and considerably faster because it can use a single allocation for both the object and its corresponding control block, eliminating a significant portion of shared_ptr's construction overhead. This eliminates one of the major efficiency complaints about shared_ptr.

    提交回复
    热议问题