C++以尽可能快的速度逐行将字符串保存到文件中



我试图尽快写入文件或将字符串s.substr (space_pos)保存在向量中。我试图用ofstream将其写入文件或用cout输出,但这需要很长时间。文本文件的大小为130mb。

这是代码:

fstream f(legitfiles.c_str(), fstream::in );
string s;
while(getline(f, s)){
size_t space_pos = s.rfind(" ") + 1;
cout << s.substr(space_pos) << endl;
ofstream results("results.c_str()");
results << s.substr(space_pos) << endl;
results.close();
}
cout << s << endl;
f.close();

有没有一种方法可以更快地写入或打印字符串?

将C++流与C流解耦:

std::ios_base::sync_with_stdio(false);

拆除cin和cout 之间的耦合

std::cin.tie(NULL);

现在不要使用std::endl不必要地在每一行之后刷新fstream缓冲区,刷新是昂贵的。您应该使用换行符n,并将缓冲区刷新留给流。

也不要构建一个你不需要的额外字符串。使用字符串_view(防止复制(

s.substr(space_pos)
//replace with:
std::string_view  view(s);
view.substr(space_pos);

如果您没有现代编译器,只需使用C字符串。

s.data() + space_pos

您正在复制子字符串。我建议创建一个临时的:

ofstream results("results.c_str()");
while(getline(f, s)){
size_t space_pos = s.rfind(" ") + 1;
const std::string sub_string(s.substr(space_pos));
cout << sub_string << "n";
results << sub_string << "n";
}
results.close();

您需要对下一个代码片段进行评测,看看它是否更快:

while(getline(f, s))
{
static const char newline[] = "n";
size_t space_pos = s.rfind(" ") + 1;
const std::string sub_string(s.substr(space_pos));
const size_t length(sub_string.length());
cout.write(sub_string.c_str(), length);
cout.write(newline, 1);
results.write(sub_string.c_str(), length);
results.write(newline, 1);
}

第二个片段背后的想法是绕过格式化过程,直接将字符串的内容写入输出流。你需要测量这两个片段,看看哪一个更快(启动一个时钟,运行一个至少1E6次迭代的例子,停止时钟。取平均值(。

如果要加快文件写入速度,请删除对std::cout的写入。

编辑1:多个线程
您可以通过使用多个线程来提高效率:"读取线程"、"处理线程"one_answers"写入线程">
"读取线程"读取行并附加到缓冲区。先开始这个。延迟后,"处理线程"对所有字符串执行substr方法
大约N个字符串处理完毕后,"写入线程"启动并将子字符串写入文件。

此技术使用双缓冲。一个线程读取数据并将其放入缓冲区。当缓冲区已满时,处理线程应该开始处理并将结果放入第二个缓冲区。当第二个缓冲区已满时,写入线程启动并将缓冲区写入结果文件。至少应有2个"读取"缓冲区和2个"写入"缓冲区。应该调整缓冲区的数量和大小,以便从程序中获得最佳性能。

//编辑:请注意,这个答案解决的问题与问题中所述的问题不同。它将跳过从行首到第一个空格(包括第一个空格(的所有内容来复制每一行。

读取一行的第一个字并在getline()读取其余字之前将其丢弃可能会更快,而不是使用string::find()std::substr()。此外,您应该避免在每次迭代中打开和关闭输出文件。

#include <string>
#include <fstream>
int main()
{
std::ifstream is{ "input" };
std::ofstream os{ "output" };
std::string str;
str.reserve(1024); // change 1024 to your estimated line length.
while (is.peek() == ' ' || is >> str, std::getline(is, str)) {
str += 'n';           // save an additional call to operator<<(char)
os << str.data() + 1;  // +1 ... skip the space
// os.write(str.data() + 1, str.length() - 1); // might be even faster
}
}

最新更新