Performance: default values for shared_ptr arguments


#1

I’ve stumbled on a pretty interesting data point.
Most of the current compilers (clang 6/gcc 8.2/MSVC17) will likely re-create std::shared_ptr ( bs::SPtr ) instance for every call that has a default argument of the form const shared_ptr<T> &arg=nullptr
A mandatory godbolt comparison

so

void bind()
{
    RenderAPI& rapi = RenderAPI_instance();
    rapi.setGraphicsPipeline(mGfxPipeline);
    rapi.setStencilRef(mStencilRef);
    rapi.setGpuParams(mParams);
}

will construct/destruct a null SPtr<CommandBuffer> 3 times.
whereas a call of the form:

void bind(const SPtr<CommandBuffer>& commandBuffer = nullptr)
{
    RenderAPI& rapi = RenderAPI_instance();
    rapi.setGraphicsPipeline(mGfxPipeline,commandBuffer);
    rapi.setStencilRef(mStencilRef,commandBuffer);
    rapi.setGpuParams(mParams,commandBuffer);
}

only constructs the null at the call site of bind


#2

That’s very interesting indeed. I’ll think about it a bit and see what would be the best way to avoid this. Possibly by having a separate set of overloads or if possible pass the command buffer parameter as a raw ptr.


#3

Another thing, it appears that std::bind can be slower then lambda and we have quite a few places that use std::bind :slight_smile:


#4

Also, if You decide on any changes, post issues on github? I or someone else might want to take a stab at them.