所以我有一个像这样的CSV格式的1GB文件,我转换为SQLite3数据库
column1;column2;column3
1212;abcd;20090909
1543;efgh;20120120
除了我有12列。现在,我需要读取和排序这些数据并重新格式化输出,但是当我尝试这样做时,似乎我的RAM耗尽(使用向量)。我从SQLite中读取它并将文件的每一行存储在一个结构中,然后将其推回到双端队列中。就像我说的,当RAM使用量接近2GB时,我的内存耗尽,应用程序崩溃了。我尝试使用STXXL,但显然它不支持非POD类型的向量(所以它必须是long int,double,char等),而我的vector主要由std :: string' s组成,有些是boost ::日期和一个双倍值。
基本上我需要做的是将所有"行"在特定列中具有相同值的一起,换句话说,我需要基于一列对数据进行排序,然后使用它。
关于我如何阅读所有内容或至少对其进行排序的任何方法?我会用SQLite3来做,但这似乎很耗时。也许我错了。
感谢。
答案 0 :(得分:1)
为了满足需求:
std::string
- 这需要额外的非连续分配,这会浪费内存。如果长度有界,则首选内联字符数组答案 1 :(得分:1)
如果你想坚持使用SQLite3方法,我建议使用列表而不是矢量,这样你的操作系统就不需要找到1GB或更多的连续内存。
如果您可以跳过SQLite3步骤,以下是解决问题的方法:
MyRow
),其中包含数据集中每列的字段。std::list<MyRow>
,其中数据集中的每一行都成为MyRow
的实例我希望这会对你有所帮助。
答案 2 :(得分:0)
std::string
的开销很大。如果您的struct
每列包含std::string
,则会在char *
指针,malloc
标题等上浪费大量空间。
尝试在阅读文件时立即解析所有数字字段,并将其作为ints
或您需要的任何内容存储在结构中。
如果您的文件实际上包含很多数字字段,例如您的示例节目,我希望它在解析后使用 less 而不是文件大小的内存。
答案 3 :(得分:0)
为您的记录创建结构。
记录应该有&#34;命令&#34;您需要排序的字段的函数。
将文件作为对象读取并存储到具有随机访问功能的容器中,例如std::vector
或std::array
。
对于要排序的每个字段:
创建索引表std::map
,使用字段值作为键,将记录索引作为值。
要按顺序处理字段,请选择索引表并遍历索引表。使用值字段(a.k.a. index)从对象容器中获取对象。
如果记录具有固定长度或可以转换为固定长度,则可以将二进制对象写入文件并将文件定位到不同的记录。使用索引表,如上所述,除了使用文件位置而不是索引。
答案 4 :(得分:0)
感谢您的回答,但我想出了一种非常快速而简单的方法。
我让SQLite3通过给它这个查询来完成这项工作:
SELECT * FROM my_table ORDER BY key_column ASC
对于一个800MB的文件,大约需要70秒来处理,然后我收到了我的C ++程序中的所有数据,已经按照我希望它们分组的列进行排序,我一次处理了一个组,并以我想要的输出格式一次输出一个,保持我的RAM不会过载。手术总时间约为200秒,我非常满意。
感谢您的时间。