Matrix sum = m1 + m2 + m3 + m4
(其中所有对象都具有类型Matrix
)“如果operator+
对象的Matrix
返回结果的代理而不是结果本身,则可以更有效地计算它。两个operator+
对象的Matrix
将返回代理类的对象,例如Sum<Matrix, Matrix>
而不是Matrix
对象。这将编码整个初始化表达式,即,比如Sum<Sum<Sum<Matrix, Matrix>, Matrix>, Matrix>
。“。
现在,我理解代理类模拟其他类的行为并进行隐式转换,但在这种情况下代理方法的效率和原因如何以及为何更有效?
祝你好运
答案 0 :(得分:1)
考虑Matrix
可能是任意大小的矩阵,因此它必须为堆中的元素分配存储空间。将两个矩阵一起添加意味着分配存储并执行逐元素复制。
在上面的表达式中,这意味着为(m1 + m2)
分配一次存储空间,将结果添加到m3
,第三次将其添加到m4
。 (移动语义可以降低此成本。)
如果添加代替返回一个代表添加的代理,同时保持对正在添加的内容的引用,则只为最终分配分配一次。
随着幕后工作的增加,可能会更加懒惰,只能按需计算结果矩阵的那些元素。
然而,这些事情总是需要权衡,你需要评估每种情况下的成本和收益。
答案 1 :(得分:0)
为演示其在代码中的工作方式,我在此处invisible proxy实现了一个示例,该示例模仿了本书中的描述。
如示例中所述,惰性求值发生在Matrix的副本Ctor(第30行)上,在该副本上实际执行计算。因为没有创建临时对象,而是直接就地计算,所以它更有效。
我还在传统的基于OO的实现和基于模板表达式的实现之间使用callgrind进行了性能比较。
设置:
结果:
template expression(成本:618037)
vs
object oriented + operator(成本:944424)