iostream vs stdio
結論としてiostream vs stdioではなく、ofstream vs fprintfの比較になってますもう過去に幾度と無くされてきた戦争な気がするのでドキュメントとして残す。
iostreamはデフォルトでstdioより遅い。
ただし、http://homepage1.nifty.com/herumi/diary/0812.html#25 のように
tie(0) + sync_with_stdio(false)を読んでおけば改善される(はず)
といってもベンチマークをとらないと何ともいえないので検証。
ってことでまずは検証ソース(ツッコミ歓迎、ちなみに560Mほどのファイルが出るので注意)
#include<cstdio> #include<vector> #include<iostream> #include<fstream> #include<boost/timer.hpp> const int loop_max = 5; const int NX=256,NY=256,NZ=256; const int DX=1./NX,DY=1./NY,DZ=1./NZ; void iotest_stdio(const std::vector<double>& data) { FILE* fp=fopen("data.dat","w"); for(int c=0;c<loop_max;++c) { for(int i=0;i<NX;++i) { for(int j=0;j<NY;++j) { for(int k=0;k<NZ;++k) { const double x=i*DX,y=j*DY,z=k*DZ; fprintf(fp,"%f %f %f\n",x,y,z,data[i*NX*NY+j*NY+k]); } } } } fclose(fp); } void iotest_stream(const std::vector<double>& data) { std::ofstream ofs("data.dat"); for(int c=0;c<loop_max;++c) { for(int i=0;i<NX;++i) { for(int j=0;j<NY;++j) { for(int k=0;k<NZ;++k) { const double x=i*DX,y=j*DY,z=k*DZ; ofs << x << " " << y << " " << z << " " << data[i*NX*NY+j*NY+k]; } } } } } int main() { std::vector<double> data(NX*NY*NZ); { std::cout << "iotest stdio : "; boost::timer timer; iotest_stdio(data); const double elapsed = timer.elapsed(); std::cout << elapsed << std::endl; } { std::cout << "iotest stream without tie(0)+sync_with_stdio(false) : "; boost::timer timer; iotest_stream(data); const double elapsed = timer.elapsed(); std::cout << elapsed << std::endl; } { std::cout << "iotest stream with tie(0)+sync_with_stdio(false) : "; std::cin.tie(0); std::ios::sync_with_stdio(false); boost::timer timer; iotest_stream(data); const double elapsed = timer.elapsed(); std::cout << elapsed << std::endl; } return 0; }
結果(環境はLinux,g++ (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2), -O3最適化)
iotest stdio : 51.38
iotest stream without tie(0)+sync_with_stdio(false) : 114.49
iotest stream with tie(0)+sync_with_stdio(false) : 114.55
tie(0) + sync_with_stdio(false)で改善されなかった!あれ?
追記:
あと
再検証結果
sync_with_stdio(false)をつけた場合のmain関数を次のように変えてます。
他は上記ソースと同じ
int main() { std::cin.tie(0); std::ios::sync_with_stdio(false); std::vector<double> data(NX*NY*NZ); { std::cout << "iotest stream with tie(0)+sync_with_stdio(false) : "; boost::timer timer; iotest_stream(data); const double elapsed = timer.elapsed(); std::cout << elapsed << std::endl; } return 0; }
iotest stdio : 51.15
iotest stream without tie(0)+sync_with_stdio(false) : 114.12
iotest stream with tie(0)+sync_with_stdio(false) : 113.29
誤差の範囲でしか変わらないですね。ツッコミまだまだ歓迎です
ちなみにtieとsync_with_stdioの呼び出し順を逆にしても同じ。
さらに追記:
ということで今回の検証は単純にfprintfとofstreamの比較ということで終わり?
stdioでの比較してませんけど、私の場合、数GB単位のデータ出力となるのでファイルへのIO以外は意味が無い。ってことで他の人にパス。