我试图尽快写入文件或将字符串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
}
}