我有一个自定义的ringbuffer实现,它使用通过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;
};
我在一个循环中重复调用ringbuffers push()
方法,用任务填充缓冲区,没有其他计算发生。我希望std::move()
只有很少的开销,绝对不会占用我计算时间的最大部分。任何人都可以指出我在这里做错了吗?
答案 0 :(得分:10)
std::move
本身在运行时没有做任何事情;它只是将其参数转换为适合传递给move-assignment运算符的 rvalue 。这是一项需要时间的任务。
如果_content[_end]
不为空,则重新分配唯一指针将删除旧对象。也许这就是花时间?