快速访问密钥文件(无需将整个文件加载到内存)

时间:2011-02-09 15:46:15

标签: c# file-io mobile performance hashtable

背景:我正在为windows mobile编写一个c#应用程序,它将从文件系统的字典中搜索Definitions(Scientific)。 该文件看起来像这样(文件有100K +条目):

 Word1:Meanings(2)
-meaning 1 bla bla bla
-meading 2 bla bla bla
[...]

用户应该能够输入一个单词并尽快获得意义。用户只会查找1或2个单词。为此,我创建了第二个文件,其中包含一个排序列表,其中包含字典文件中的实际字和字节偏移量。 例如:

word1:12344
word2:32241
word3:298

我查看我的“索引”(简单循环遍历所有行并进行比较,如果相等)然后使用字节偏移“随机访问”字典文件。 问题是,这仍然是缓慢的。 我尝试将索引加载到数组/列表/哈希表中,但由于速度较慢,这需要太长时间(加载索引大约需要20秒)。这很糟糕,因为用户通常只会查找一个单词。 因此,我正在寻找某种类型的n-tree实现,它可以直接在文件上工作(不遍历整个索引)。 有人有建议如何做到这一点? 我目前的解决方案看起来像这样(但有缺陷和脏): 新索引具有以下格式:

a:FileOffsetInDictionary:FileOffsetOf"ab" //the first 2 character starting with a
b:FileOffsetInDictionary:FileOffsetOf"ba"
c:FileOffsetInDictionary:0 //"0" means that their are no words starting with "c" (just for example)
[...]
ab:FileOffsetInDictionary:FileOffsetOf"aba"
ac:FileOffsetInDictionary:878878 //(just some random values for illustration)
[...]
ba:FileOffsetInDictionary:456
[...]
aba:FileOffsetInDictionary:2342
[...]

以这种方式进行搜索:

Users enter the word "Tree"
Look for "t" in index by looping through the index
if "t" found then goto FileOffsetOf2Digit
if "tr" found then goto FileOffsetOf3Digit
[...]
[actually recursively coded]

2 个答案:

答案 0 :(得分:1)

正确的答案可能是告诉你使用b-tree索引,这对于这种性质的基于磁盘的索引是理想的,或者更好的是如果你谈论的是移动6.5及更早版本,你可以使用SQL CE数据库。您可以找到许多实现,但如果没有,您可以执行以下操作。

使用当前索引文件构思的内容,使每个索引记录固定大小。因此,如果您知道该字永远不会超过50个字符并且偏移量将适合四字节整数,则可以在索引文件中创建54个字节的记录条目(假设字符为ASCII,相应地进行调整)。然后,您可以对索引文件执行binary search,而不是扫描整个文件以访问每条记录。

答案 1 :(得分:1)

如果您必须自己实施,则应构建整个语料库的trie。这比已知数据的B树,红黑树或哈希表更快,并且可以存储部分匹配。即如果用“T”调用它,它将在你的语料库中返回字符“T”的第一个实例。如果你用“r”调用它并提供“T”的第一个实例,它将返回语料库中的第一个“Tr”实例,而不必先搜索“T”等等。