Comparing the performance of a sequence of several generatorsを見てBoost.Spirit.Karmaのフォーマット出力が優秀だと知ったのですが、最近のgccとboostだとどうなるかと思って自分のLinux環境でも実行してみました。
(実行環境: boost: 1.54.0, gcc: 4.8.2 コンパイルオプション: -O3, -std=c++1y, CPU: Core i3 4130T)
ソースは上記ページのものにsnprintfも加えたものを実行しました。(最近はセキュルティの観点でsprintfよりsnprintfが推奨されるため)
処理内容は、12345.12345という小数2つから[12345.123 12345.123 ]という文字列(小数点以下3桁、14文字分のスペース)を繰り返し生成するものです。
すると、Spirit.Karmaがsprintfの4倍近く速いことが分かりました。(-O2オプションでもほとんど同じ結果でした。)
sprintf: 1.13721 snprintf: 1.12995 iostreams: 1.39023 format: 1.99459 karma: 0.231521 karma (string): 0.318302 karma (rule): 0.294326
※iostremasはstd::stringstream、formatはboost::formatを指しています。
また、元々のソースでは12345.12345が直に書かれていたので、定数の最適化が行われている可能性を考えて標準入力から数値を与えるようにソースを改変してみましたが、結果はほとんど変わりませんでした。
疑いようもなくSpirit.Karmaが速いです。
input a decimal 12345.12345 input one more decimal 12345.12345 sprintf with args: 1.14024 snprintf with args: 1.12748 iostreams with args: 1.38619 format with args: 2.01176 karma with args: 0.228151 karma (string) with args: 0.314551 karma (rule) with args: 0.293565
なお、数値の桁数が小さい時は差が縮まりました。
input a decimal 1.0 input one more decimal 2.0 sprintf with args: 0.412689 snprintf with args: 0.393523 iostreams with args: 0.640817 format with args: 1.2292 karma with args: 0.263695 karma (string) with args: 0.327404 karma (rule) with args: 0.307239
Boost.Spirit.Karmaはコードが複雑でコンパイル時間も増えるのでカジュアルに使うのには向かないですが、処理速度を求める時には最適なようです。
カジュアルに使う場合は、処理速度は遅いですがsprintf風の記法で型安全でもあるboost::formatが使いやすいですね。
std::stringstreamは、数値を入れる時に余計なバッファを確保するので遅いようです。(boost::formatよりは速いですが。)
ちなみに、int型をstd::string型に変換するのみの場合でもSpirit.Karmaは速いようです。
C++ Convert Int to String Speed
これを見てもうひとつ分かるのは、boost::lexical_castがsprintf以上に速いということです。
カジュアルに数値を文字列に変換するだけなら、boost::lexical_castがベストチョイスになりそうです。
(C++11以降ではstd::to_stringという選択肢もありますが、こちらの処理速度等の詳細は未確認です。)
0 件のコメント:
コメントを投稿