13 More Effective C++—条款18(超前分期计算)
1 超前分期计算若程序经常用到,某个需要大量计算的值,那我们不如就直接将这个值算出来。比较典型的例子是,在读取一堆数字的时候,顺便把平均值、最大值、最小值都算出来。比如: class Data { public: double max(); double min(); void readData(); ........ private: double m_max,m_min; } 这种方式(暂存数据:称为cache)之所以能够节省时间,是因为,如果所读取的数据集很大,并且其不经常变化,那我们每次获得像max,min的值,免去遍历整个数据集的工作,提高程序运行效率。 但是,如果数据集经常变化,这种方式不会带来太大改善。 2 应用这种方式主要针对如下场景: 1,获取某个结果,需要进行大量计算;或者,进行一次操作很费时间——如IO操作。 2,并且,涉及到的数据,不经常变化。 满足以上两个要求,这种方法才真正适用。 3 数据库访问饭店为了提高顾客就餐体验,每个包间会起一个十分别致的名字。每个包间名唯一对应一个编号。 包间名称,房间号 因为包间名称和房间号基本无变化,且数据库查询操作会启用IO,响应时间过长。因此,可以一次性将房间名和房间号读入内存缓存,直接访问内存查询。 房间号和房间名一 一对应,因此可以采用bi-direct-order map,即键值可以互查——key可以查询value,value可以查询key。 4 预获取(pre-fetch)1 std::vector的预先分配策略“超前分期计算”重点在于“超前”。因此,各种操作,都可以通过牺牲存储容量来换取时间——在程序无法进一步优化的前提下,不可能空间和时间效率都有提高。 比如,如果没有预先分配内存计数,std::vector就会在每次插入数据时,进行如下操作: 1,重新分配更大的内存 2,将原有数据拷贝到新的内存空间 3,插入新数据 显然,这样做效率很低。 实际上,在每次std::vector使用容量达到上限后,会分配原来的两倍内存,后面即便再插入数据,也不会进行上面的复杂动作。 2 内存的预先分配策略计算机中,按照访问速度,由快到满排序是:高速缓存 -> 内存 -> 磁盘。容量由小到大排序是:高速缓存 -> 内存 ->磁盘。因此,CPU会优先读取高速缓存中的数据。 每个进程包含程序指令和数据,占用存储空间。为了加速运行,进程会取出一些当前用不到的数据,放到内存和高速缓存中——空间交换时间。 但是,如果进程占用空间过多,线程总数过多,就会导致数据频繁在内存和磁盘之间交换,程序执行速度反而下降。我们采用“缓存命中率(cache hit rate)”来描述一段时间内,真正用到的数据与存储中实际用到的数据之比。 缓存命中率 = (真正用到的数据) / (在内存中的数据,或者告诉缓存中的数据) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |