将大量数据加载到 .net 中的列表 <MyObject>
Loading large amounts of data into a List<MyObject> in .net
我有一个 C# 工具可以解析一组 csv 文件以构建一个列表。此集合可以小到 20 个文件,也可以大到 10000 多个文件。 MyObject 它自己有大约 20 个属性,其中大部分是字符串。每个文件有时最多可以在列表中创建 4 个项目,有时多达 300 个。
解析完成后,我首先将列表保存到 csv 文件中,这样我以后就不必再次重新解析数据了。然后我通过数据集的一个数据集汇总数据,然后用户可以选择数据集的多个数据集。数据在 WPF 中呈现,用户对数据进行操作并使用一些附加信息对数据进行注释,然后将这些信息添加到 MyObject。最后,用户可以将所有这些信息保存到另一个 csv 文件中。
我 运行 当文件变大并优化了我的一些代码时,我进入了 OOM。首先我意识到我正在存储一个参数,即 csv 文件的路径,有时接近 255 个字符。我将其更改为仅保存文件名,并且情况略有改善。然后我发现了一个编译为 x64 的建议,它将给我 4 Gb 的内存而不是 2 Gb。
尽管如此,当越来越多的文件添加到该数据集时,我显然遇到了 OOM。
我考虑过的一些选项是:
解析文件时,每个文件解析后保存到intermediate.csv文件,不在内存中保存列表。这将有助于我避免在保存 intermediate.csv 文件之前看到 OOM 的步骤。
这种方法的问题是,一旦解析完成,我仍然必须将中间文件加载回内存。
MyObject 的某些属性与文件集合相似。所以我考虑过将单个对象重构为多个对象,这可能会减少 List 对象中的项目数。本质上重构为 List,MyTopLevelDetailsObject 包含一个 List。内存占用量理论上应该减少。然后我可以通过做一些 t运行slation 使它看起来像一个单一的对象,将它输出到 csv。
将数据移动到内部数据库,如 MongoDB 并加载数据以汇总到数据库逻辑。
改用数据表。
选项 2 和 3 将进行重大重新设计,其中 3 也需要我学习 MongoDB。 :)
我正在寻找有关如何处理大型数据集的一些指导和有用的提示。
此致,
长城
如果优化后数据无法放入内存,几乎根据定义,您需要将其写入磁盘。
与其重新发明轮子并创建自定义数据格式,通常最好使用一种经过严格审查的解决方案。 MongoDB 在这里是一个不错的选择,其他数据库解决方案也是如此。我喜欢 SQLite,尽管名称不同,但它可以处理大量数据并且不需要本地服务器。
如果您遇到在本地磁盘上安装数据的问题,您可能会考虑转向大型数据解决方案,如 Hadoop。不过,这是一个更大的话题。
选项二和选项四可能对您没有帮助,因为(如我所见)它们不会减少内存中的信息总量。
同时考虑动态加载数据的选项。我的意思是,用户可能无法在某一时刻看到所有数据。因此,您可以将 .csv 的一部分加载到内存中并将其显示给用户,然后如果用户做了一些 annotations/edits 您可以将这块数据保存到一个单独的文件中。如果用户滚动浏览数据,您会即时加载它。当用户想要保存最终的 .csv 时,您可以将它从原始文件和您保存的小块中组合起来。
在创建访问大量数据的 C# 桌面应用程序时,这通常是一种做法。例如,当我需要创建一个 WinForms 软件来操作一个巨大的数据库(超过 1000 万行的表,它们不适合普通的办公室 PC 内存)时,我采用了动态加载数据块的方式。
是的,手动使用 .csv 完成工作量太大。 使用一些数据库 来处理 saving/saving 编辑的 parts/composition 最终输出会更容易。
我有一个 C# 工具可以解析一组 csv 文件以构建一个列表。此集合可以小到 20 个文件,也可以大到 10000 多个文件。 MyObject 它自己有大约 20 个属性,其中大部分是字符串。每个文件有时最多可以在列表中创建 4 个项目,有时多达 300 个。
解析完成后,我首先将列表保存到 csv 文件中,这样我以后就不必再次重新解析数据了。然后我通过数据集的一个数据集汇总数据,然后用户可以选择数据集的多个数据集。数据在 WPF 中呈现,用户对数据进行操作并使用一些附加信息对数据进行注释,然后将这些信息添加到 MyObject。最后,用户可以将所有这些信息保存到另一个 csv 文件中。
我 运行 当文件变大并优化了我的一些代码时,我进入了 OOM。首先我意识到我正在存储一个参数,即 csv 文件的路径,有时接近 255 个字符。我将其更改为仅保存文件名,并且情况略有改善。然后我发现了一个编译为 x64 的建议,它将给我 4 Gb 的内存而不是 2 Gb。
尽管如此,当越来越多的文件添加到该数据集时,我显然遇到了 OOM。
我考虑过的一些选项是:
解析文件时,每个文件解析后保存到intermediate.csv文件,不在内存中保存列表。这将有助于我避免在保存 intermediate.csv 文件之前看到 OOM 的步骤。 这种方法的问题是,一旦解析完成,我仍然必须将中间文件加载回内存。
MyObject 的某些属性与文件集合相似。所以我考虑过将单个对象重构为多个对象,这可能会减少 List 对象中的项目数。本质上重构为 List,MyTopLevelDetailsObject 包含一个 List。内存占用量理论上应该减少。然后我可以通过做一些 t运行slation 使它看起来像一个单一的对象,将它输出到 csv。
将数据移动到内部数据库,如 MongoDB 并加载数据以汇总到数据库逻辑。
改用数据表。
选项 2 和 3 将进行重大重新设计,其中 3 也需要我学习 MongoDB。 :)
我正在寻找有关如何处理大型数据集的一些指导和有用的提示。
此致, 长城
如果优化后数据无法放入内存,几乎根据定义,您需要将其写入磁盘。
与其重新发明轮子并创建自定义数据格式,通常最好使用一种经过严格审查的解决方案。 MongoDB 在这里是一个不错的选择,其他数据库解决方案也是如此。我喜欢 SQLite,尽管名称不同,但它可以处理大量数据并且不需要本地服务器。
如果您遇到在本地磁盘上安装数据的问题,您可能会考虑转向大型数据解决方案,如 Hadoop。不过,这是一个更大的话题。
选项二和选项四可能对您没有帮助,因为(如我所见)它们不会减少内存中的信息总量。
同时考虑动态加载数据的选项。我的意思是,用户可能无法在某一时刻看到所有数据。因此,您可以将 .csv 的一部分加载到内存中并将其显示给用户,然后如果用户做了一些 annotations/edits 您可以将这块数据保存到一个单独的文件中。如果用户滚动浏览数据,您会即时加载它。当用户想要保存最终的 .csv 时,您可以将它从原始文件和您保存的小块中组合起来。
在创建访问大量数据的 C# 桌面应用程序时,这通常是一种做法。例如,当我需要创建一个 WinForms 软件来操作一个巨大的数据库(超过 1000 万行的表,它们不适合普通的办公室 PC 内存)时,我采用了动态加载数据块的方式。
是的,手动使用 .csv 完成工作量太大。 使用一些数据库 来处理 saving/saving 编辑的 parts/composition 最终输出会更容易。