条款十八:分期摊还预算的计算成本

来源:互联网 发布:dota2淘宝买饰品 编辑:程序博客网 时间:2024/03/29 22:53

条款十八:分期摊还预算的计算成本

  函数实现总共有三种方式:1. 实时评估(eager evaluation);2. 缓式评估(Lazy evaluation);3. 急式评估(over-eager evaluation)。三种方式都有实用的场景,之前我们讨论过缓式评估(Lazy evaluation),是尽可能的拖延做某件事,但是这种方法并不适应于任何环境如果你需要做一件经常要做的事情时,拖延可并不是一个比较好的方案。这里我们将说道急式评估,就是指尽可能的提前做某件事。

1. Caching

  如果你需要经常取一个数据,那么事先将数据保存好不就很号吗。
  比如你要经常取一个数据,我们可以将他保存在一个缓存中并且进行实时的更新这样就不会因为多次取同一个值而造成重复的操作(下面的例子是关于从数据库中取一些信息):

    //get the number of a employee    int find_number(const string& employee_name)    {        typedef map<string,int> cache_map;               //暂存        static cache_map _cache_map;        //find a memeber in the map        cache_map::iterator it = _cache_map.find(employee_name);        if(_cache_map.end() == it)        {            //TODO:get data from database            //TODO:add the data into the map        }        else        {            return (*it).second;        }    }

  上面的例子是从数据库中取出一个员工的编号,并且将经常取到的员工数据在缓存中实时更新。这样当多次取同一个数据时的效率就会有不错的提高。over-eager evaluation的目的是降低平均效率,和之前的实现方法相同必须考虑使用的环境。

2. Prefetching

  Prefetching(预先取出)是另一种做法,比如当你需要从磁盘中读取数据时,即使你需要的只是少量的数据,但系统还是会读取一个块,因为读取一个块比读取小块数据要快,而且当你读取一小块数据时,旁边的数据被需要的概率也相对比较大,系统就是这样为你取数据。
  这个当然也可以使用在代码的优化上,比如动态分配数组,比较一般的做法时当数组到达上界时就将数组进行扩展,但是这样做如果一直需要对数组进行数据的插入时,这样做的效率因为不断调用内存分配函数不断下降。为何我们不每次动态分配时给他分配一个块呢比如将内存扩展为原来的多少倍之类的,这样做不是更加合理?可能你的数组不需要这么大内存空间但是相比于处理数据比较多的情况时的代价还是不错的。

总结

  我们可以明显现的看到急式评估是在用内存空间的牺牲来获取效率,所以说这两者之间需要一个平衡,我们不能为了代码的效率不顾系统的内存,也不能为了节省内存放弃代码的运行效率,需要将平衡控制在二者之间,这个需要你自己判断。而且上述的是一种编程的思想不要只用C++取思考他,抽象他是最好的,它适用于任何语言。

0 0
原创粉丝点击