将trie保存到磁盘

时间:2010-09-20 01:28:04

标签: c# performance data-structures persistence trie

这听起来像一个简单的问题,但我不知道如何寻找答案。

我在C#中有一个trie实现,它将存储来自字典文件的大约80K字。加载所有这些单词(超过5分钟)需要很长时间。我想知道,“持久化”这些数据的最佳方法是什么,所以每次启动应用程序时我都不必重新加载所有单词?

感谢。

3 个答案:

答案 0 :(得分:5)

与所有其他性能问题一样,理想的解决方案将从分析您当前的解决方案和您提出的其他候选解决方案开始。瓶颈在哪里? I / O?翻译文字?在trie中形成链接?在不了解您的性能目标,当前使用的特性和瓶颈的性质的情况下,很难提出具体的建议。

需要考虑的问题:

  1. 存储格式:文字?二进制?
  2. 持久化数据:trie的整个结构(例如XML)或仅仅是一个单词列表,依靠运行时代码将它们推送到数据结构中的正确位置?什么是数据比率加成?解析有多重?
  3. 存储地点:DB / flat-file / ...?
  4. 增量加载:可能?
  5. 一种可能的策略:使用最常用单词的1,000(左右)创建并保留“最常用单词”字典。在启动时将这些单词加载到trie中,并在另一个线程上生成完整字典的加载;在读取新单词时逐步添加到创建的trie。

    • 优点:用户将看到更快的启动时间。
    • 缺点:可能需要跨线程 同步,用户会看到一个 不完整的trie直到装载 完全完成。这可能是也可能不是showstopper,具体取决于trie的用途。

答案 1 :(得分:2)

由于性能低下和序列化/反序列化时间较慢,我最近重构了类似的数据结构。

我的解决方案是完全废弃trie并使用本机.NET集合 - 字典和查找。

我正在使用大约400k字。从内存中构建数据结构大约需要5秒钟,这是一个由多个字典和查找索引的对象列表。

  • 结构的顶层是a Dictionary<int, var>所在的关键 是n - 中的字母数 搜索词。
  • 中的每个值 dictionary是Lookup<string, string>,其中键是一个字符串 有n个字母,价值就是全部 以该字符串开头的字符串。 例如,关键'st'值可能是 'start','stop'和'string'。

为了创建数据结构,我简单地遍历i = 1到maxlength的整个单词列表,以创建每个i的所有不同'start with'字符串的Lookup。将它们插入顶级词典,你就完成了。

这消除了对定制构建的需求。我发现性能差异(搜索时间)可以忽略不计,但加载速度非常有利于我的设计(更不用说使用简单.NET类型的简单性和可维护性)。

答案 2 :(得分:0)

我只是用旧的MFC二进制方式序列化它。基本上读/写应该尽可能快,并且你唯一剩下的就是在输入上分配和初始化结构,无论如何你需要做。

也就是说,为了序列化trie的节点,你可以这样做:

Read/Write number N of subnodes
For each subnode
  If reading, allocate a subnode in this node
  Read/Write the character for the subnode
  Serialize the subnode
End

编辑:重新阅读你的问题,你想从wordlist中从头开始构建trie?正如其他人所说,简介,但不只是与任何旧的探查者。他们并不都能找到你的问题。 Here's what I do.所花费的时间不应超过读取文件所需的时间加上创建结构所需的时间。