编程交流与学习--More Effective C++的学习-Item M17:考虑使用lazy evaluation(懒惰计算法)

本文介绍了懒惰计算法(lazyevaluation)的概念及其在不同场景中的应用,包括字符串对象的引用计数、区别对待读取和写入操作、懒惰提取及懒惰表达式计算等。通过这些方法可以有效提高程序的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
从效率的观点来看,最佳的计算就是根本不计算.关键是要懒惰。lazy evaluation(懒惰计算法)。 eager evaluation(热情计算).
l         引用计数
String s1 = "Hello";
String s2 = s1;                 / 调用string拷贝构造函数
    通常string拷贝构造函数让s2被s1初始化后,s1和s2都有自己的”Hello”拷贝。这种拷贝构造函数会引起较大的开销。然而这时的s2并不需要这个值的拷贝,因为s2没有被使用。
    lazy evaluation:除非你确实需要,不去为任何东西制作拷贝。我们应该是懒惰的,只要可能就共享使用其它值。
l         区别对待读取和写入
    继续讨论上面的reference-counting string对象。来看看使用lazy evaluation的第二种方法。考虑这样的代码:
String s = "Homer's Iliad";            // 假设是一个reference-counted string
cout << s[3];                         // 调用 operator[] 读取s[3]
s[3] = 'x';                           // 调用 operator[] 写入 s[3]
    我们应能够区别对待读调用和写调用,因为读取reference-counted string是很容易的,而写入这个string则需要在写入前对该string值制作一个新拷贝。通过使用lazy evaluation和条款M30中讲述的proxy class,我们可以推迟做出是读操作还是写操作的决定,直到我们能判断出正确的答案。
l         Lazy Fetching(懒惰提取)
    因为LargeObject对象实例很大,为这样的对象获取所有的数据,数据库的操作的开销将非常大,特别是如果从远程数据库中获取数据和通过网络发送数据时。而在这种情况下,不需要读去所有数据。当LargeObject对象被建立时,不从磁盘上读取所有的数据,这样懒惰法解决了这个问题。不过这时建立的仅是一个对象“壳”,当需要某个数据时,这个数据才被从数据库中取回。
l         Lazy Expression Evaluation(懒惰表达式计算)
Matrix<int> m1(1000, 1000);                   // 一个 1000 * 1000 的矩阵
Matrix<int> m2(1000, 1000);                   // 同上
Matrix<int> m3 = m1 + m2;                     // m1+m2
    lazy evaluation方法说这样做工作太多,所以还是不要去做。
cout << m3[4];                                // 打印m3的第四行
    很明显,我们不能再懒惰了,应该计算m3的第四行值。
    实际上lazy evaluation就存在于APL语言中。APL是在1960年代发展起来语言,能够进行基于矩阵的交互式的运算。那时侯运行它的计算机的运算能力还没有现在微波炉里的芯片高,APL表面上能够进行进行矩阵的加、乘,甚至能够快速地与大矩阵相除!它的技巧就是lazy evaluation。这个技巧通常是有效的,因为一般APL的用户加、乘或除以矩阵不是因为他们需要整个矩阵的值,而是仅仅需要其一小部分的值。APL使用lazy evaluation 来拖延它们的计算直到确切地知道需要矩阵哪一部分的结果,然后仅仅计算这一部分。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值