字典树trie分析报告

来源:互联网 发布:js对话框 模式 非模式 编辑:程序博客网 时间:2024/06/02 23:33

由于项目中需要优化原有std::map红黑树实现的目录树,调研了trie树及其变种Ternary Search Trie的原理,并做了相应的性能测试。

1 支持前缀查找(自动补齐,比如fuse中ls -al) 2 支持高效范围查找 3 支持内存量的减少(类似设计模式中的享元模式)
      测试对象:
      Std::map 红黑树    来自标准模板库实现
      Patricia Trie 压缩trie   来自标准模板库ext实现
      Ternary search Tree 三叉树    来自wiki的一个STL-compliant的开源实现
      测试结果:
测试1
向stl::map、tst、stl::PAT分别插入1到100W数据,并查找这些数据。
tst
$./otst 
start to insert
insert use ms:5530
start to search
search use ms:3692
size = 1000000
内存:
VmSize:   110168 kB


map:
$./omap 
start to insert
insert use ms:2712
start to search
search use ms:1625
size = 1000000
内存:
VmSize:   121172 kB


PAT:
$./opat 
start to insert
insert use ms:4163
start to search
search use ms:985
size = 1000000
内存:
VmSize:   311796 kB


一,     map的插入性能最优,pat的查找性能最优,tst插入查找性能都较差。
二,     pat最耗内存,在数据量较大时,tst消耗内存接近map, tst在fuse这种情景下内存理应是最小的。
三,     tst和pat自身提供prefix_range这些范围查找函数。
测试2:
向map和tst插入前缀相同的一些字符串,检查内存消耗。
这些字符串大小为100M+2,其中前100M的数据都相同,仅最后一个字符不同。共插入10个这样的数据,分别记录插入第一个和所有都插入后的内存。
tst:
仅插入第一个字符串:
VmSize:  4411012 kB
全插入后:
VmSize:  4308608 kB(猜测是三叉树的rebalance的原因)


map:
仅插入第一个字符串:
VmSize:   216684 kB
全插入后:
VmSize:   933512 kB


总结:当字符串的前缀相同时,tst的公用字符机制可以很有效的节省内存。


总结:
      Map的性能适中,但自身不支持范围查找和前缀查找,需要自身代码实现。相对效率较低
      PatTrie的查找性能很强,根据测试,并没有相应的共享前缀节点,导致占用内存不理想。
      Ternary tree其实是一颗变种的trie树,insert find效率都不高,由于每个字符占用一个节点,而red-black的一个key占用一个节点,相对树的层次会比red-black高(在节点相似度不高的情况下)。但内存和前缀查找均很好的支持。

0 0
原创粉丝点击