【问题标题】:Clone function speed: if/else vs short circuit evaluation克隆功能速度:if/else vs 短路评估
【发布时间】:2014-01-13 02:42:58
【问题描述】:

我正在调整一种分析大量数据的算法,以使其运行得更快一些。它大量使用了clone 函数,如下所示:

const Object* clone() const {
    if (this != INVALID_OBJECT) {
        return new DerivedObject(*this);
    } else {
        return this;
    }
}

该算法使用指向单个无效对象的指针来显着减少内存需求,并且通过复制构造函数传递它会破坏目的。

我的问题是使用短路评估是否会通过减少执行时间来提高 clone 函数的性能:

const Object* clone() const {
    const Object* clonedObject = INVALID_OBJECT;
    (void)((this != INVALID_OBJECT)&&(clonedObject = new DerivedObject(*this));
    return clonedObject;
}

有什么方法可以减少clone 函数的执行时间?复制构造函数通常遵循模式

DerivedObject(const DerivedObject& derivedObj) : Object(derivedObj.getField1()),
    field2(derivedObj.getField2()) {}

【问题讨论】:

  • 除了使您的代码更难阅读和维护之外,这两个函数可能没有什么不同并生成相同的目标代码。
  • 你分析过你的代码吗?
  • 问问自己,克隆有必要吗?我可以改用引用计数吗?
  • @Jarod42 还没有,我才刚刚开始优化,克隆函数几乎是唯一有任何分支的函数
  • 因此,分析您的代码,您将看到需要优化的地方。我很确定这不是您的克隆方法的瓶颈。

标签: c++ performance short-circuiting


【解决方案1】:

您的优化虽然看起来很复杂,但实际上微不足道,因为它可能会发出与前一个相同的代码。

考虑低级操作,而不是语法:一个条件,一个分支。少做多难。

更新:我注意到我没有真正回答您的问题:可以更快地完成吗?嗯,是!您可以为未初始化的值编写一个子类。

class InvalidObject : public Object
{
public:
    const Object* clone() const {
        return this;
    }
};

并使全局INVALID_OBJECT 成为此类的一个实例:

Object *INVALID_OBJECT = new InvalidObject();

现在您不需要任何 clone() 覆盖中的条件:

class DerivedObject : public Object
{
public:
    const Object* clone() const {
        return new DerivedObject(*this);
    }
};

当然,根据您的层次结构和INVALID_OBJECT 实例的定义,您可能需要为每个DerivedObject 类型编写一个Invalid* 子类。

【讨论】:

  • 可能。我读过短路评估可以更快,但在这种情况下,我可以看到由于额外的分配,它可能会产生 更多 低级操作
  • @mablem:即使是额外的分配也会被编译器优化掉。我认为这两段代码几乎相同。
  • 另一个可能的优化机会是使用final 关键字(class InvalidObject final : public Objectconst Object* DerivatedObject::clone() const final
猜你喜欢
  • 2017-09-10
  • 2012-12-16
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 2016-10-19
  • 2015-11-14
相关资源
最近更新 更多