std::move()作为性能瓶颈?

5

我有一个定制的环形缓冲区实现,它使用通过 new [] 分配的普通数组,然后使用 std::move 将元素移入数组。这是我的 push() 方法的实现:

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

我正在向数组中移动的对象基本上只是一个指针和一个std::unique_ptr

struct Task
{
    Task()
    {}

    Function function;
    Batch *batch;
};

函数的格式如下:

function
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;
};

我在循环中重复调用环形缓冲区的push()方法,以填充任务缓冲区,这里没有其他计算。我期望std::move()的开销非常小,绝对不会占用大部分计算时间。有人能指导我我做错了什么吗?


1
你是怎么确定的?任何值得一试的编译器优化器都不应该让 std::move 调用生效。 - R. Martinho Fernandes
我将Instruments附加到程序中,并捕获了大约两分钟的运行时间。它标记了我将数据移入数组的那一行,占用了9.2%的执行时间(如注释中所示)。使用最新的Xcode 5附带的Clang编译,使用-Os选项,没有调试信息或运行时断言。 - JustSid
6
不是std::move,而是你对象的移动构造函数。我不确定你在这里期望什么:如果你只是把东西放进缓冲区,那么把东西放进缓冲区(即移动它)将是最常见的活动。 - R. Martinho Fernandes
1
std::move只是一个编译时转换,不会生成任何运行时代码。更准确地说,std::move(value)等同于static_cast<value_type&&>(value)。它在运行时不会产生任何开销。 - Cassio Neri
4
如果_content[_end]不为空,则分配唯一指针将删除旧对象。也许这就是花费时间的原因? - Mike Seymour
显示剩余11条评论
1个回答

13

std::move本身在运行时什么也不做;它只是将其参数转换为适合传递给移动赋值运算符的rvalue。 花费时间的是赋值操作。

如果_content [_end]不为空,则重新分配唯一指针将删除旧对象。也许这就是花费时间的原因?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接