Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29650
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 69
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-26 14:33
文章分类
文章存档

2014年(6)

我的朋友
最近访客

分类: C/C++

2014-09-05 16:24:18

over-eager evaluation背后的概念是:如果你预期程序常常会用到某个计算,你可以降低
每次计算的平均成本,办法就是设计一份数据结构以便能够极有效率的处理需求。

最简单的一个做法就是将“已经计算好而且有可能再被需要”的数值保留下来(caching)。
例如楼主项目中的发送报文部分,系统可分为一级系统、二级系统,二级系统下还有其隶属的
下级支撑系统及下下支撑系统等。这些系统间可自由通信,当然可能有的只是转发消息而已。
也就是说发送报文的目的地有n个,其中在组织报文的时候通常是根据其系统唯一标识uuid去
数据库中查询其系统号+主机号+实体号,就是山东省滨州市阳信县的隶属关系。假如当程序运行
起来我们需要给系统A发送消息,于是便到去数据库获取系统号+主机号+实体号,然后组织报文
发送消息,如果我们下次还需要给系统A发送消息呢?我们还是到数据库中去获取系统号+主机号+
实体号那就费时了,我们可以使用局部缓存来存储系统A的uuid和系统号+主机号+实体号之间的
对应关系,下次给某系统发送报文时,先到局部缓存中寻找有没有其相关的信息,假如没有找到,
我们只好到数据库中去获取,然后存入缓存中,但是假如找到的话,可是省去了不少力气的,
昂贵的数据查询动作怎么能比廉价的内存查找来的实在。

大致实现:
/**********************************************************************************/
typedef struct
{
  ...//系统号+主机号+实体号
}STINFO;
int sendMsg(char* uuid, ...)
{
 static std::map staticMap_msg;
 STINFO stInfo = {0};
 
 if(staticMap_msg.count(uuid) == 0)
 {
  ...//数据库查询动作
  
  /*
  memcpy(&stInfo, ..., sizeof(STINFO));
  */
  /*
  对于map而言在插入新数据的时候使用insert较好,在更新已有数据时使用下标操作较好
  所以暂未使用staticMap_msg[uuid] = stInfo;
  */
  staticMap_msg.insert(std::map::value_type(uuid, stInfo));
 }
 else
 {
  stInfo = staticMap_msg[uuid];
 }
 
 ...//组织报文发送数据
 return 0;
}
/**********************************************************************************/

注意事项:
(1)必须确保数据库中uuid和STINFO的对应关系式不仅仅是一一对应,而且还要保证一成不变。
(2)map不能无限变大才较好,如有无限大的可能性,空间换时间需慎重考虑。可对map的insert操作
加限制条件,如必须是一、二级系统等等。
(3)上述操作没有加锁,多线程操作需谨慎,此处是指的在n个工作线程组织报文的话需谨慎,假如是
在发送线程的话则无此忧患(毕竟发送线程只有一个,会组织好先后顺序)。
(4)为什么是局部缓存,而不放在全局的部分。如果程序只对STINFO作为发送目的地感兴趣的话,干嘛
将其暴露出一个全局的访问点呢?

over-eager evaluation一个典型的例子就是vector的自增长。vector会自动增长以便容下你放入其中的
数据,只要没有超过它们的最大限制就可以。vector的增长过程是这样实现的:每当需要更多的空间时,
(1)分配一块大小为当前容量的某个整数倍(一般为2倍吧)的新内存。也就是说多预留了好多空间。
(2)把容器内的所有元素从旧的内存中复制到新的内存中
(3)析构掉旧内存的对象
(4)释放掉旧内存
这样做的好处就是通过预留更多的内存使vector更加有弹性,不必每次都去执行上面的4步(当然预留空间
用完时还是必须去执行上述4步的,^_^)。

阅读(1595) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~