我正在实施一种搜索类型(TF-IDF),其中每个单词的分数都与所搜索的所有文档成比例。我有100GB的文件要搜索。
如果我使用1GB文件,我会使用:
Dictionary<string, List<Document>>
..其中string
是单词,List<Document>
是按顺序排列的所有文档,包含该单词。这不会扩大规模。我使用Dictionary<>
,因为查找时间是O(1)(理论上)。
我想要的解决方案是一个SQLServer数据库,其中的单词列在表中,相关的List对象存储为序列化。我担心的是,每次读取数据库并重建为List<>
都会非常低效。
我在这方向走错了吗?使用庞大的词典有什么正常的解决方案?
答案 0 :(得分:6)
你说对List
使用效率低是正确的,平均List
会达到线性输出(O(n)
)。
就个人而言,我会使用保证为O(1)
的Concurrent Dictionary
。在我参与的一个项目中,我正在处理大文件100MB的文本文件,我发现Concurrent Dictionary
可以充分排序和搜索信息,每秒钟完成估计10,000条给予或记录。
看看这个整洁的cheat sheet。对于Big-Oh算法,它为最佳和最差情况提供了一些简洁的细节。在处理海量数据集时,记住Abstraction
和Decomposition
的概念非常重要。
抽象专注于最重要的元素 - 忽略不相关的细节
只存储重要的信息,我非常怀疑你需要一个完整的1GB文件才能在内存中。
分解分而治之
确保运行应用程序的桌面具有良好的数据库延迟。我建议只在内存中存储你需要的东西,并使用LINQ只检索你需要的确切信息,一旦你掌握了与你的任务相关的信息......你就可以进一步过滤它。
答案 1 :(得分:0)
如果内存不是问题,我会使用你的代码。如果列表是性能问题,请将其设为字典。在DB中保存是很好的,因为它很快并且不需要大量内存。
这只是一个直觉问题。我的选择是数据库和良好的索引。每次调用数据库。如果性能很关键,请将其保存在内存中,就像你一样,并以某种方式将字典替换为字典。
答案 2 :(得分:0)
我同意你的意见,我曾经做过像你这样的任务,但我的数据远远少于你的。我认为字典对于您的单词搜索及其重要文档很有用,因为它可以保持单词与文档的关系,并且您可以轻松查询和排序单词。关于你的担忧,我认为阅读数据库并重建为List&lt;&gt;效率不高,但如果您经常重建和更新列表,可能需要通过其他方式对其进行优化,例如服务器磁盘中的文件缓存,而不是经常将长文本值更新到数据库。 祝你好运!
答案 3 :(得分:0)
我只是在谈您应该如何存储/检索数据。我会尝试使用Dictionary
如果您正在构建网站,则没有理由返回每个文档的全部内容。您只需返回文档名称即可,因为用户可以选择要阅读的文档。