代理类C++优势
C++ Advantage of Proxy Classes
斯科特·迈耶斯(Scott Meyers)在"有效的现代C++"中说,表达式
Matrix sum = m1 + m2 + m3 + m4
(其中所有对象都有类型Matrix
)"如果operator+
forMatrix
对象返回结果的代理而不是结果本身,则可以更有效地计算。也就是说,两个Matrix
对象的operator+
将返回代理类(如Sum<Matrix, Matrix>
)的对象,而不是Matrix
对象。这将对整个初始化表达式进行编码,即类似于Sum<Sum<Sum<Matrix, Matrix>, Matrix>, Matrix>
."。
现在,我知道代理类模拟其他一些类的行为并执行隐式连接,但是在这种情况下代理方法如何以及为什么更有效?
此致敬意
考虑到Matrix
可能是一个任意大小的矩阵,因此它必须从堆中为其元素分配存储。将两个矩阵相加意味着分配存储并执行逐元素复制。
在上面的表达式中,这意味着为(m1 + m2)
分配一次存储,以将其结果添加到m3
,第三次将其添加到m4
。(移动语义可以降低此成本。
如果添加返回一个代理,该代理仅表示添加,同时保存对要添加的事物的引用,则只为最终分配分配一次。
随着幕后工作的增多,可能会更加懒惰,按需只计算结果矩阵中需要的那些元素。
但是,这些事情始终是一种权衡,您需要评估每种情况下的成本和收益。
为了演示它在代码中的工作方式,我在这里实现了一个示例,它模仿了书中的描述。
如示例中所述,惰性计算发生在矩阵的副本 Ctor(第 30 行)上,实际执行计算。它更有效,因为不会创建临时对象,而是直接就地计算。
我还使用调用研磨在传统的基于 OO 的实现和基于模板表达式的实现之间进行性能比较。
设置:
- 矩阵大小: (1, 2000)
- 待评估表达式:mat_a + mat_a + mat_a + mat_b + mat_c;
结果:
模板表达式(成本:618037)
与
面向对象 + 运算符(成本:944424)
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- 使用融合乘法累加实现双精度有多大优势?
- 在现代C++中,侵入式容器是否仍然比非侵入式容器具有性能优势?
- 与传统的多态处理相比,使用 std::variant 有什么优势?
- CRTP相对于抽象类的优势
- __stdcall的优势/用途是什么?
- unique_ptr相对于shared_ptr的优势是什么
- 新功能"synchronized"块在C++中提供了什么优势?
- C++ 与 C 语言相比,I/O 文件流的优势
- 除了 std::string_view 方法之外,std::string_view 比 char* 有什么优势吗?
- 使用C 函子进行比较的优势
- 使用此类型函数有什么优势
- 前向迭代器多通道保证的优势
- 类成员函数在C++中相互调用有什么优势?
- 在 C++ 中,映射相对于堆的优势是什么?
- 在QT资源系统中,前缀比文件系统路径的优势是什么?
- 在C 中的Boost库中可辍学的蓄能器的优势是什么?
- 如果链表比数组具有许多功能优势,那么数组与链表相比有什么优势?
- 定义仅调用私有函数的公共函数有什么优势
- 使用STD ::可选避免函数中的默认参数有任何优势