C ++代理类的优势

时间:2017-11-28 15:51:19

标签: c++ c++11

斯科特迈耶斯在“有效的现代C ++”中说过表达

Matrix sum = m1 + m2 + m3 + m4

(其中所有对象都具有类型Matrix)“如果operator+对象的Matrix返回结果的代理而不是结果本身,则可以更有效地计算它。两个operator+对象的Matrix将返回代理类的对象,例如Sum<Matrix, Matrix>而不是Matrix对象。这将编码整个初始化表达式,即,比如Sum<Sum<Sum<Matrix, Matrix>, Matrix>, Matrix>。“。

现在,我理解代理类模拟其他类的行为并进行隐式转换,但在这种情况下代理方法的效率和原因如何以及为何更有效?

祝你好运

2 个答案:

答案 0 :(得分:1)

考虑Matrix可能是任意大小的矩阵,因此它必须为堆中的元素分配存储空间。将两个矩阵一起添加意味着分配存储并执行逐元素复制。

在上面的表达式中,这意味着为(m1 + m2)分配一次存储空间,将结果添加到m3,第三次将其添加到m4。 (移动语义可以降低此成本。)

如果添加代替返回一个代表添加的代理,同时保持对正在添加的内容的引用,则只为最终分配分配一次。

随着幕后工作的增加,可能会更加懒惰,只能按需计算结果矩阵的那些元素。

然而,这些事情总是需要权衡,你需要评估每种情况下的成本和收益。

答案 1 :(得分:0)

为演示其在代码中的工作方式,我在此处invisible proxy实现了一个示例,该示例模仿了本书中的描述。

如示例中所述,惰性求值发生在Matrix的副本Ctor(第30行)上,在该副本上实际执行计算。因为没有创建临时对象,而是直接就地计算,所以它更有效。

我还在传统的基于OO的实现和基于模板表达式的实现之间使用callgrind进行了性能比较。

设置:

  • 矩阵大小:(1,2000)
  • 要评估的表达方式:mat_a + mat_a + mat_a + mat_b + mat_c;

结果:

template expression(成本:618037)

vs

object oriented + operator(成本:944424)