将大量数据加载到 .net 中的 List<MyObject>

Posted

技术标签:

【中文标题】将大量数据加载到 .net 中的 List<MyObject>【英文标题】:Loading large amounts of data into a List<MyObject> in .net 【发布时间】:2016-11-25 18:06:57 【问题描述】:

我有一个 C# 工具,它可以解析一组 csv 文件以构造一个列表。此集合可以小到 20 个文件,也可以大到 10000+ 个文件。 MyObject 它本身有大约 20 个属性,其中大部分是字符串。每个文件有时最多可以在列表中创建 4 个项目,有时多达 300 个。

解析完成后,我首先将列表保存到 csv 文件,这样我以后就不必再次重新解析数据。然后,我通过数据集的一个轴来汇总数据,然后用户可以选择数据集的多个轴。数据显示在 WPF 中,用户对数据进行操作并使用一些附加信息对数据进行注释,然后将这些信息添加到 MyObject。最后,用户可以将所有这些信息保存到另一个 csv 文件中。

当文件变大并优化了我的一些代码时,我遇到了 OOM。首先,我意识到我正在存储一个参数,即 csv 文件的路径,有时接近 255 个字符。我将其更改为仅保存文件名,情况略有改善。然后我发现了一个编译到 x64 的建议,它会给我 4 Gb 的内存而不是 2 Gb。

即便如此,当越来越多的文件添加到该数据集中时,我显然还是遇到了 OOM。

我考虑过的一些选项是:

    解析文件时,在每个文件解析后保存到intermediate.csv 文件,而不是将列表保存在内存中。这对我来说可以避免在我保存 middle.csv 文件之前看到 OOM 的步骤。 这种方法的问题是,一旦解析完成,我仍然必须将中间文件加载回内存。

    MyObject 上的某些属性与文件集合类似。所以我考虑将单个对象重构为多个对象,这可能会减少 List 对象中的项目数。本质上重构为 List,MyTopLevelDetailsObject 包含一个 List。内存占用理论上应该减少。然后我可以通过进行一些翻译将其输出到 csv 以使其看起来像单个对象。

    在内部将数据移动到类似 MongoDB 的数据库中,并加载数据以汇总到数据库逻辑。

    改用数据表。

选项 2 和 3 将进行重大重新设计,其中 3 也需要我学习 MongoDB。 :)

我正在寻找有关如何处理大型数据集的一些指导和有用的提示。

问候, 长宽

【问题讨论】:

对于这么多的数据,数据库是最好的选择。 本质上,您的应用程序是一个内存数据库,正如您所见,它有其局限性。建议您使用基于磁盘的数据库存储系统。即选择您最喜欢的 RDBMS 【参考方案1】:

如果经过优化后,数据无法放入内存,几乎按照定义,您需要它来访问磁盘。

与其重新发明***并创建自定义数据格式,不如使用经过充分审查的解决方案之一。 MongoDB 是一个不错的选择,其他数据库解决方案也是如此。我喜欢 SQLite,尽管它有这个名字,但它可以处理大量数据并且不需要本地服务器。

如果您遇到将数据安装到本地磁盘上的问题,您可能会考虑转向 Hadoop 等大数据解决方案。不过,这是一个更大的话题。

【讨论】:

我可能会选择 SQLite 选项。将节省我很多时间,而不是重做数据结构。谢谢匿名。 @loganwol,+1 SQLite 可能会为您提供已经实现的所有功能【参考方案2】:

选项二和四可能无法帮助您,因为(在我看来)它们不会减少内存中的信息总量。

还可以考虑动态加载数据的选项。我的意思是,用户可能无法在某一时刻看到所有数据。因此,您可以将 .csv 的一部分加载到内存中并将其显示给用户,然后如果用户进行了一些注释/编辑,您可以将此数据块保存到单独的文件中。如果用户滚动浏览数据,您可以即时加载它。当用户想要保存最终的 .csv 文件时,您可以将原始文件和您保存的小块组合在一起。

在创建访问大量数据的 C# 桌面应用程序时,这通常是一种做法。例如,当我需要创建一个 WinForms 软件来操作一个庞大的数据库(超过 10m 行的表,它们无法容纳普通的办公室 PC 内存)时,我采用了动态加载数据块。

是的,手动使用 .csv 完成的工作量太大。 使用一些数据库更容易来处理保存/保存已编辑的部分/最终输出的组合。

【讨论】:

首先出现的摘要视图是这样的,它可以在 DataGrid 中少于 10 行,但集合的数量可以是 1000,每个集合代表大约 30 个 csv 文件,导致 3000 个项目列表。 我不明白这有多重要。我的想法是“用 .csv 文件实现您自己的简单非关系数据库,因为它是支持数据源”。所以信息可以保存在磁盘上而不是内存中。接下来如何处理它以及使用哪些对象取决于您。

以上是关于将大量数据加载到 .net 中的 List<MyObject>的主要内容,如果未能解决你的问题,请参考以下文章

Java SwingWorker 将数据从数据库加载到 List

如何在每个 Worker 中的 Spark Dataframe 中加载数据,以防止将大量数据加载到 Master 节点

怎么将list集合中的数据加载到Map中

ASP.NET MVC 组合框值加载

java 将一个有大量数据的list集合分成指定大小的list集合

单击日历时将数据加载到 PartialView (ASP.NET MVC)