重定向到文件的 c++ cout 工作速度比使用 ofstream 慢
c++ cout redirected to file works slower than using ofstream
我有一个应用程序必须遍历每个字符(以检查一些特殊情况)并使用 ostream put 方法将其写入流。
将 ostream* 指向文件流时,它的执行速度比将 ostream* 指向重定向到文件的 cout 时要快得多。
在这个 () 回答中,我看到使用 fstream 可能会更快,因为与 cout 相比多了一层缓冲。
我想当我知道输出要到cout时,我可以通过一个字符串缓冲区,当缓冲区已满时,将它追加到cout。
这样我就获得了另一层缓冲,性能会有所提高。
所以我这里有一个写3200万行的测试,每行是一个十个字符的字符串。
我使用 cout、fstream 和后来附加到 cout 的 stringbuffer 编写它们。
void print_to_ostream(ostream *out, string& ones)
{
for (int i = 0; i < 32000000; ++i){
const char* ones_char = ones.c_str();
for (int j = 0; j < ones.size(); ++j ){
out->put(ones_char[j]);
}
}
}
int main(void){
string ones ="1111111111";
ostream *out = &cout;
size_t cout_time = 0;
size_t file_time = 0;
size_t cout_buffered_time = 0;
// print cout using ostream
mono_tick_timer time;
print_to_ostream(out, ones);
cout_time += time.tick();
// write to file using ostream
ofstream file("/tmp/test_file");
out = &file;
time.tick();
print_to_ostream(out, ones);
file_time += time.tick();
// ***optional solution***
// print to cout but passing through a string buffer
stringstream buffer;
out = &buffer;
time.tick();
print_to_ostream(out, ones);
cout_buffered_time += time.tick();
cout << buffer.str();
size_t buf_to_cout = time.tick();
std::cerr << "cout time: " << (double)cout_time / 1e6 << endl;
std::cerr << "file time: " << (double)file_time / 1e6 << endl;
std::cerr << "cout buffered time: " << (double)cout_buffered_time / 1e6 << endl;
std::cerr << "buf_to_cout: " << (double)buf_to_cout / 1e6 << endl;
return 0;
}
结果运行./a.out > /tmp/test_times
如下(毫秒):
cout time: 4773.62
file time: 2391.52
cout buffered time: 2380.83
buf_to_cout: 131.615
我的底线问题是:在附加所有内容之前使用 stringstream 作为缓冲区是否是一个好的解决方案?
考虑到有时 cout 被重定向到一个文件的大输出,有时它只是被打印到控制台?
是否有我没有考虑过此解决方案的负面影响?
或者有更好的我没想到的?
全局流(例如 std::cout
)默认为 sync_with_stdio
,而 std::ofstream
不是:
By default, all eight standard C++ streams are synchronized with their respective C streams.
If the synchronization is turned off, the C++ standard streams are allowed to buffer their I/O independently, which may be considerably faster in some cases.
尝试使用 std::cout.sync_with_stdio(false);
将其关闭。
我有一个应用程序必须遍历每个字符(以检查一些特殊情况)并使用 ostream put 方法将其写入流。
将 ostream* 指向文件流时,它的执行速度比将 ostream* 指向重定向到文件的 cout 时要快得多。
在这个 () 回答中,我看到使用 fstream 可能会更快,因为与 cout 相比多了一层缓冲。 我想当我知道输出要到cout时,我可以通过一个字符串缓冲区,当缓冲区已满时,将它追加到cout。 这样我就获得了另一层缓冲,性能会有所提高。
所以我这里有一个写3200万行的测试,每行是一个十个字符的字符串。 我使用 cout、fstream 和后来附加到 cout 的 stringbuffer 编写它们。
void print_to_ostream(ostream *out, string& ones)
{
for (int i = 0; i < 32000000; ++i){
const char* ones_char = ones.c_str();
for (int j = 0; j < ones.size(); ++j ){
out->put(ones_char[j]);
}
}
}
int main(void){
string ones ="1111111111";
ostream *out = &cout;
size_t cout_time = 0;
size_t file_time = 0;
size_t cout_buffered_time = 0;
// print cout using ostream
mono_tick_timer time;
print_to_ostream(out, ones);
cout_time += time.tick();
// write to file using ostream
ofstream file("/tmp/test_file");
out = &file;
time.tick();
print_to_ostream(out, ones);
file_time += time.tick();
// ***optional solution***
// print to cout but passing through a string buffer
stringstream buffer;
out = &buffer;
time.tick();
print_to_ostream(out, ones);
cout_buffered_time += time.tick();
cout << buffer.str();
size_t buf_to_cout = time.tick();
std::cerr << "cout time: " << (double)cout_time / 1e6 << endl;
std::cerr << "file time: " << (double)file_time / 1e6 << endl;
std::cerr << "cout buffered time: " << (double)cout_buffered_time / 1e6 << endl;
std::cerr << "buf_to_cout: " << (double)buf_to_cout / 1e6 << endl;
return 0;
}
结果运行./a.out > /tmp/test_times
如下(毫秒):
cout time: 4773.62
file time: 2391.52
cout buffered time: 2380.83
buf_to_cout: 131.615
我的底线问题是:在附加所有内容之前使用 stringstream 作为缓冲区是否是一个好的解决方案? 考虑到有时 cout 被重定向到一个文件的大输出,有时它只是被打印到控制台?
是否有我没有考虑过此解决方案的负面影响? 或者有更好的我没想到的?
全局流(例如 std::cout
)默认为 sync_with_stdio
,而 std::ofstream
不是:
By default, all eight standard C++ streams are synchronized with their respective C streams.
If the synchronization is turned off, the C++ standard streams are allowed to buffer their I/O independently, which may be considerably faster in some cases.
尝试使用 std::cout.sync_with_stdio(false);
将其关闭。