Update
@Ruslan pointed me to Why is snprintf consistently 2x faster than ostringstream for printing a single number? which provides an answer and a link to a bug report.
Original question
My general feeling indicates that using C++ ofstream
and <<
operators should be of similar performance, provided I do not use endl
but literal "\n"
instead to skip the implicit flushing.
Also, this question supports my thought.
So, in the following example I'd expect the runtime to be genrally similar with slight advantages on the streaming side.
#include <cstdio>
#include <string>
#include <fstream>
#include <boost/timer/timer.hpp>
using namespace std;
const int LOOPS = 10000000;
const double d = 1.231;
const float f = 1.232;
const char *s = "1.233";
void stream_out() {
boost::timer::auto_cpu_timer t;
ofstream out;
out.open("ofstream");
for(int i = 0; i < LOOPS; ++i) {
out << d << "\n";
out << f << "\n";
out << s << "\n";
}
}
void print_out() {
boost::timer::auto_cpu_timer t;
FILE* fout = fopen("fprintf", "w");
for(int i = 0; i < LOOPS; ++i) {
fprintf(fout, "%g\n", d);
fprintf(fout, "%g\n", f);
fprintf(fout, "%s\n", s);
}
}
int main() {
stream_out();
print_out();
return 0;
}
However, that does not appear to be the case. When built with g++ and run on my RHEL7 box this shows:
$ g++ --version
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -O2 -o test test.cpp -lboost_timer -lboost_system
$ ./test
7.697337s wall, 6.660000s user + 0.160000s system = 6.820000s CPU (88.6%)
4.724694s wall, 4.580000s user + 0.130000s system = 4.710000s CPU (99.7%)
So, what is my misunderstanding here?
Shouldn't ofstream
be ever-so-slightly faster since it doesn't need to parse format strings and variadic args at runtime?
Do I miss something obvious?
It'd be a shame to revert to fprintf()
just of such performance differences.