内存映射文件列表实现,用于在内存中存储大型数据集
本文关键字:内存 存储 大型 数据集 映射 文件 列表 实现 用于 | 更新日期: 2023-09-27 18:08:40
我需要按时间顺序对实现为IList的巨大时间序列执行操作。数据最终存储到数据库中,但是向数据库提交数千万个查询是没有意义的。
当前,当尝试存储超过800万个(小)对象时,内存中的IList会触发OutOfMemory异常,尽管我需要处理数千万个对象。
经过一番研究,看起来最好的方法是将数据存储在磁盘上,并通过IList包装器访问它。
内存映射文件(在。net 4.0中引入)似乎是正确的接口,但我想知道写一个应该实现IList(便于访问)并在内部处理内存映射文件的类的最佳方法是什么。
我也很好奇你是否知道其他的方法!例如,我考虑使用来自db40的数据的illist包装器(这里有人提到使用内存映射文件作为IoAdapterFile,尽管使用db40与直接处理内存映射文件相比可能会增加性能成本)。
我在2009年遇到过这个问题,但它没有产生有用的答案或严肃的想法。
我发现了这个PersistentDictionary<>,但它只适用于字符串,通过阅读源代码,我不确定它是为非常大的数据集设计的。
更具可扩展性(高达16 TB), ESENT PersistentDictionary<>使用Windows (XP+)中存在的ESENT数据库引擎,可以存储包含简单类型的所有可序列化对象。
基于磁盘的数据结构,包括字典,列表和数组与"智能"序列化器看起来完全像我正在寻找的,但它并没有顺利运行与非常大的数据集,特别是因为它没有利用"原生". net MemoryMappedFiles,对32位系统的支持是实验性的。
更新1:我最终实现了自己的版本,广泛使用。net MemoryMappedFiles;它非常快,一旦我使它更好地用于更通用的用途,我可能会在Codeplex上发布它。
更新2: TeaFiles。Net也很适合我的目的。强烈推荐(并且免费)。
我看到几个选项:
- "in-memory-DB"
例如,SQLite可以这样使用-不需要任何设置等,只需将DLL(1或2)与应用程序一起部署,其余的可以通过编程完成 - 将所有数据加载到临时表(s)到DB中,具有未知(但大)的数据量,我发现这样做的回报非常快(并且处理通常可以在DB内完成,这甚至更好!)
- 使用MemoryMappedFile和固定的结构大小(通过偏移量进行类似数组的访问),但要注意物理内存是限制,除非您使用某种"滑动窗口"将部分仅映射到内存
内存映射文件是一种很好的方法。但是如果你需要随机访问的话,它将会非常慢。
你最好的办法可能是想出一个固定的结构大小保存在内存中(如果可以的话),然后你使用偏移量作为列表项id。然而,删除/排序总是一个问题。