Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::move() as performance bottleneck?

I have a custom ringbuffer implementation which uses a normal array allocated via new [], and then uses std::move to move elements into the array. Here is the implementation of my push() method:

void push(value_type&& value)
{
    _content[_end] = std::move(value); // 9.2% of execution is spend here
    increment(); // 0.6% here
}

The objects I'm moving into the array are basically just a pointer and a std::unique_ptr:

struct Task
{
    Task()
    {}

    Function function;
    Batch *batch;
};

And Function looks like this:

class Function
{
public:
    template<typename F>
    Function(F&& f) :
        _implementation(new ImplementationType<F>(std::move(f)))
    {}

    void operator() () { _implementation->Call(); }

    Function() = default;
    Function(Function&& other) :
        _implementation(std::move(other._implementation))
    {}

    Function& operator=(Function&& other)
    {
        _implementation = std::move(other._implementation);
        return *this;
    }

    Function(const Function&) = delete;
    Function(Function&) = delete;
    Function& operator= (const Function&) = delete;

private:
    struct Base
    {
        virtual void Call() = 0;
        virtual ~Base() {}
    };

    template<typename F>
    struct ImplementationType : Base
    {
        ImplementationType(F&& f) :
            function(std::move(f))
        {}

        void Call()
        {
            function();
        }

        F function;
    };

    std::unique_ptr<Base> _implementation;
};

I call the ringbuffers push() method repeatedly in a loop to fill the buffer up with tasks, there is no other computation happening there. I would expect the std::move() to have very little overhead, and definitely not eat up the biggest chunk of my computation time. Can anyone point me into the right direction of what I'm doing wrong here?

like image 774
JustSid Avatar asked Oct 21 '13 16:10

JustSid


1 Answers

std::move itself does nothing at runtime; it just casts its argument into an rvalue suitable for passing to the move-assignment operator. It's the assignment that will be taking time.

If _content[_end] isn't empty, then reassigning the unique pointer will delete the old object. Perhaps that's what's taking the time?

like image 84
Mike Seymour Avatar answered Oct 30 '22 11:10

Mike Seymour