【发布时间】:2014-09-11 04:38:25
【问题描述】:
我有一个 7GB 的文本文件,其中包含多行记录,这些记录由仅包含标记“$$$$”的行分隔。
我编写了一个方法来拆分它,一次解析一行,测试令牌,然后进行相应的拆分。这个想法是以循环方式将每个多行记录写入不同的输出文件。我的代码如下:
// Open all temp files for reading
int nThreads = threadData.size();
std::vector<ofstream*> ostrms(nThreads);
for (int i = 0; i < nThreads; ++i)
{
ostrms[i] = new ofstream(threadData[i].InFileName);
if (! ostrms[i]->is_open() )
return(false);
}
// parse mol records into temp files in round-robin fashion
std::vector<std::string> molRecord;
std::string line;
const std::string MOL_END_OF_RECORD = "$$$$";
int curOutfileNo = 0;
while( ! strm.eof() )
{
std::getline(strm,line);
if (line.find(MOL_END_OF_RECORD) != std::string::npos)
{
for (int i = 0; i < molRecord.size(); ++i)
*(ostrms[curOutfileNo]) << molRecord[i] << "\n";
(*ostrms[curOutfileNo]) << line << "\n";
curOutfileNo = (curOutfileNo+1) % nThreads;
molRecord.clear();
}
else
molRecord.push_back(line);
}
for (int i = 0; i < nThreads; ++i)
delete ostrms[i];
这非常运行缓慢(几分钟)。有更快的方法吗?
7GB 的文本文件有 245,634,858 行和 466537 条由“$$$$”分隔的唯一记录
【问题讨论】:
-
为什么要换行?为什么不直接搜索“$$$$”?
-
@FoggyDay 因为我想将多行记录写入他们自己的文件。所以我想把我的 7Gb 分成 4 个 1.75-ish GB 的文件,里面有完整的记录。
-
您是否对运行进行了基准测试,例如wc(1) 在你的大文件上?如果您的程序运行例如,请不要感到惊讶。比
wc慢 10 倍 ... -
很遗憾 wc 和 grep -c 都花了至少一分钟
-
while( ! strm.eof() )已损坏 - 使用while (std::getline(strm, line))。鉴于wc至少需要一分钟,并且您的程序的写入和读取预计会增加一倍以上,如果输出到同一个驱动器,那么基本 I/O 操作听起来会非常接近您已经提到的“几分钟”......如果无论如何您都迫切希望提高性能,也许可以尝试使用内存映射 I/O:您可以写出由指针分隔的区域,而不需要类似于molRecord的任何内容。