首页 / 软件开发 / 数据结构与算法 / 谈表达式树的缓存(7):五种缓存方式的总体分析及改进方案
谈表达式树的缓存(7):五种缓存方式的总体分析及改进方案2011-09-30 博客园 Jeffrey Zhao终于到了这个系列的最后一篇文章了,这个系列的文章本是许多话题的基础,却拖了那么长时间还没 有完结。这篇文章主要讨论五种缓存方式各自的优劣,以及他们的性能关键在什么地方,如果要进行改进 又有什么可选方案。在这个问题上,老赵的思考可能会有遗漏,如果您有任何补充,也请不吝指出。SimpleKeyCacheSimpleKeyCache是最直接的缓存方案:将表达式树进行完整编码,将其转化为一个独一无二的字符串 ,然后作为Key存放到字典中。从上一篇文章的实验来看,无论从耗时还是对GC造成的压力上来说,SimpleKeyCache都是五种缓存方 案中最差的。这一点倒很容易理解。因为在.NET中拼接字符串是一种相对来说消耗巨大的操作。而将一个 表达式树进行完整编码,势必要将它的各种信息都存放到字符串中。此时您就会发现,例如表达式树的每 个节点中的Type或MemberInfo信息会占用较大的空间,同时一颗表达式树内部的节点数量也可能比较可观 。两者相辅相成,使得构造一个字符串的代价就非常显著了。不过,SimpleKeyCache的优点是什么呢?它的优点就在于,它是五种缓存方案中唯一“能够任意重现 ”的方案。也就是说,无论是在哪台机器上,无论是哪一次启动,相同表达式树的编码结果是不变的。这 也是实现“分布式存储”的必要条件。之前文章中所提到的各种缓存方案都是在单个进程内实现的,因此 只要在程序启动之后某些必要信息不会改变(例如某个对象的GetHashCode调用结果)即可。但是在分布 是存储环境中,会出现多个进程多台机器,如果它们产生的“键”无法保持不变,就无法使用相同表达式 树进行可持续的通信了。如果您真的在“分布式存储”环境,或是其他需要“稳定”特性的场景下(例如把一个表达式树存入 数据库)使用表达式树作为标识符,那么您可以选择的做法可能是优化编码方案了。例如,您可以把最终 的字符串进行分段,在header中写入Type对象的信息并为它指定一个简短的表识符,这样在字符串的body 里就可以省去对大量数据的重复了。不过,复杂的编码也可能带来额外的运算开销,对于性能不一定会带来好处。因此,在得出确定的结 论之前,一定要对实现进行性能评测,不用感觉,而是用数据说话。