在 C# 中使用非常大的 Dictionary<>
Posted
技术标签:
【中文标题】在 C# 中使用非常大的 Dictionary<>【英文标题】:Working with very large Dictionary<> in C# 【发布时间】:2014-01-02 16:46:00 【问题描述】:我正在实现一种搜索类型 (TF-IDF),其中每个单词的计算分数都与正在搜索的所有文档成正比。我有 100GB 的文档要搜索。
如果我使用 1GB 的文档,我会使用:
Dictionary<string, List<Document>>
..其中string
是单词,List<Document>
是所有文档,按顺序排列,包含该单词。这不会扩大规模。我使用的是Dictionary<>
,因为查找时间是 O(1)(理论上)。
我想要的解决方案是一个 SQLServer 数据库,其中单词被列在一个表中,相关的 List 对象被序列化存储。我担心的是每次读取数据库并重建到List<>
效率会非常低。
我是不是走错了方向?处理庞大字典的正常解决方案是什么?
【问题讨论】:
我会考虑使用磁盘支持的存储机制:请参阅各种 Hash/Hierarchial “NoSQL”选项。 我会让其他人回答你的问题,但我建议使用 MongoDB 来解决这个问题。它的创建正是考虑到了这种类型的东西。它有一个 .net 驱动程序,它的工作方式与实体框架大致相同。 【参考方案1】:您说得对,使用List
效率低下,平均而言,List
将实现线性输出 (O(n)
)。
就个人而言,我会使用Concurrent Dictionary
,它保证是O(1)
。在我参与的一个项目中,我正在处理 100MB 文本文件的大文件,我发现 Concurrent Dictionary
可以充分地对信息进行分类和搜索,每秒完成大约 10,000 条记录。
看看这个整洁的cheat sheet。对于 Big-Oh 算法,它为最好和最坏的情况提供了一些简洁的细节。在处理海量数据集时,牢记Abstraction
和Decomposition
的概念很重要。
抽象专注于最重要的元素 - 忽略不相关的细节
只存储重要的信息,我非常怀疑你是否需要一个完整的 1GB 文件才能在内存中。
分解分而治之
确保运行您的应用程序的桌面对您的数据库具有良好的延迟。我建议仅将您需要的内容存储在内存中,并使用 LINQ 仅检索您需要的确切信息,一旦您拥有与您的任务相关的信息......然后您可以进一步过滤它。
【讨论】:
谢谢,我会看看那个数据结构。我的基本问题仍然存在;在内存/虚拟内存中存储 100GB 是不可行的。 如果我的回答有助于解决您的问题,如果您将其标记为正确答案,我们将不胜感激。问候。【参考方案2】:如果内存不是问题,我会使用您的代码。如果列表是性能问题,那么也将其作为字典。将内容保存在 DB 中很好,因为它速度快且不需要大量内存。
这只是直觉的问题。我的选择是数据库和良好的索引。每次调用数据库。如果性能至关重要,请像您一样将其保存在内存中,并以某种方式将列表替换为字典。
【讨论】:
【参考方案3】:我同意你的观点,我曾经做过像你这样的任务,但我的数据比你的少得多。我认为字典对您的单词搜索及其相关文档很有用,因为它可以保持单词与文档的关系,并且您可以轻松查询和排序单词。关于您的问题,我认为读取数据库并重建到 List 效率并不低,但是如果您非常频繁地重建和更新列表,则可能需要通过其他方式进行优化,例如服务器磁盘中的文件缓存,而不是经常将长文本值更新到数据库。 祝你好运!
【讨论】:
【参考方案4】:我只是在讨论您应该如何存储/检索数据。我会尝试 Dictionary
如果您正在构建网站,则没有理由返回每个文档的全部内容。您只需要返回文档的名称,因为用户可以选择他们想要阅读的文档。
【讨论】:
以上是关于在 C# 中使用非常大的 Dictionary<>的主要内容,如果未能解决你的问题,请参考以下文章