我有一个C#工具,它解析一组csv文件来构造一个List。此集合可以小到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。记忆足印应该在理论上减少。然后,我可以通过进行一些转换将其输出到csv,使其看起来像一个对象。
在内部将数据移动到类似MongoDB的数据库并加载数据以汇总到数据库逻辑。
改为使用DataTable。
选项2和3将重新设计,3还需要我学习MongoDB。 :)
我正在寻找有关如何处理大型数据集的一些指导和有用的提示。
此致 LW
答案 0 :(得分:4)
如果在优化之后,数据无法容纳在内存中,几乎按定义你需要它才能打到磁盘上。
通常最好使用经过良好审查的解决方案,而不是重新发明轮子并创建自定义数据格式。与其他数据库解决方案一样,MongoDB是一个不错的选择。我喜欢SQLite,尽管有这个名字,它可以处理大量数据并且不需要本地服务器。
如果您遇到了在本地磁盘上安装数据的问题,您可能会考虑继续使用Hadoop等大型数据解决方案。不过,这是一个更大的话题。
答案 1 :(得分:1)
选项二和四不能帮助你,因为(我认为)它们不会减少内存中的信息总量。
还要考虑动态加载数据的选项。我的意思是,用户可能无法在一个时刻看到所有数据。因此,您可以将.csv的一部分加载到内存并将其显示给用户,然后如果用户进行了一些注释/编辑,您可以将这些数据块保存到单独的文件中。如果用户滚动数据,您可以即时加载它。当用户想要保存最终的.csv时,你将它与原始的和你保存的小块组合起来。
创建访问大量数据的C#桌面应用程序时,这通常是一种做法。例如,当我需要创建一个WinForms软件来运行庞大的数据库(行数超过10米的表,它们不适合平庸的办公室PC内存)时,我采用了动态加载数据。
是的,手动使用.csv做太多工作。 使用某些数据库更容易处理已编辑部件的保存/保存/最终输出的组合。