条款16 谨记80-20法则
80-20 准则说的是大约 20%的代码使用了 80%的程序资源;大约 20%的代码耗用了大约 80%的运行时间;大约 20%的代码使用了 80%的内存;大约 20%的代码执行 80%的磁盘访问;80%的维护投入于大约 20%的代码上;通过无数台机器、操作系统和应用程序上的实验这条准则已经被再三地验证过。80-20 准则不只是一条好记的惯用语,它更是一条有关系统性能的指导方针,它有着广泛的适用性和坚实的实验基础
条款17 考虑使用 lazy evaluation(缓释评估)
从效率上来看,最好的运算就是未被执行过的运算,但是这是不可能的,既然不用我们就没有必要将它加到程序中.
那么下面介绍一种战术"lazy evaluation(缓释评估)",所谓的缓释平时评估就是拖延战术,如果你采用缓式评估来编写你的类,使他们延缓运算,直到哪些运算结果刻不容缓地被迫切需要为止.如果其运算结果一直不被需要,也就一直不执行.
那么我们先介绍一种缓式评估
1.Reference Counting(引用计数)
考虑下面的代码
class String { ... }; // 一个字符串类(标准的string类型,为了描述下面的技术实现,不过并非一定如此) String s1 = "Hello"; String s2 = s1; //调用 string 拷贝构造函数
一旦s2 = s1,那么其拷贝构造函数就会被调用,那么我们就存在两个"Hello"的副本(eager evaluation急式评估),调用new operator 来为s2分配内存
这时我们考虑一下,如果s2只做一些类似于读的操作(例如下面的代码),那么我么就没有必要去新new出一个String,我们只需要将s1和s2共享即可
cout << s1; // 读 s1 的值 cout << s1 + s2; // 读 s1 和 s2 的值
但是如果我们即要读又要写的话那么数据共享就行不通,比如说我只想修改s2那么我们就 必须要为s2创建一个"副本".为了处理这样的case,我们需要添加如下语句
s2.convertToUpperCase();
在这个方法实现中我们必须令String.converToUpperCase()函数为s2的内容做一个副本,并且在修改s2之前先让该副本成为s2的私有数据,在converToUpperCase()函数内我们不能再拖延了,我们必须将s2(被共享的内容做一个副本,给s2私人使用).另一方面如果s2从未被改变,如果我们够幸运,s2从未被改过,那么我们就始终不用去new它.(相应实现我们会在条款29中详细叙述)
2.Lazy Fetching(缓式取出)