I was running some benchmarks to find the most efficient way to write a huge array to a file in C++ (more than 1Go in ASCII).
So I compared std::ofstream with fprintf (see the switch I used below)
case 0: {
std::ofstream out(title, std::ios::out | std::ios::trunc);
if (out) {
ok = true;
for (i=0; i<M; i++) {
for (j=0; j<N; j++) {
out<<A[i][j]<<" ";
}
out<<"\n";
}
out.close();
} else {
std::cout<<"Error with file : "<<title<<"\n";
}
break;
}
case 1: {
FILE *out = fopen(title.c_str(), "w");
if (out!=NULL) {
ok = true;
for (i=0; i<M; i++) {
for (j=0; j<N; j++) {
fprintf(out, "%d ", A[i][j]);
}
fprintf(out, "\n");
}
fclose(out);
} else {
std::cout<<"Error with file : "<<title<<"\n";
}
break;
}
And my huge problem is that fprintf seems to be more thant 12x slower compared to std::ofstream. Do you have an idea of what is the origin of the problem in my code ? Or maybe std::ofstream is very optimized compared to fprintf ?
(and an other question : do you know another faster way to write a file)
Thank you very much
(detail : I was compiling with g++ -Wall -O3)
fprintf("%d"
requires runtime parsing of the format string, once per integer. ostream& operator<<(ostream&, int)
is resolved by the compiler, once per compilation.
Well, fprintf()
does have to do a bit more work at runtime, since it has to parse and process the format string. However, given the size of your output file I would expect those differences to be of little consequence, and would expect the code to be I/O bound.
I therefore suspect that your benchmark is flawed in some way.
fsync()/sync()
at the end?There is a file buffer in the ofstream, this may decrease the times accessing to the disk. in addition, fprintf is a function with variable parameters which will call some va_# functions, but ofstream won't.I think you can use fwrite() or putc() to have a test.
Have you set sync_with_stdio somewhere upstream of the code you have shown?
While what you report is opposite that of what is empirically seen, most people think and believe what you see should be the norm. iostreams are type-safe, whereas the printf family of functions are variadic functions that have to infer the types of the va_list from the format specifier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With