[C++]数式パーサーADAPT-FMPは本当にExprTkより速いのか。

自作ライブラリの話。
以前、ADAPT-FMPという文字列数式計算を行うためのライブラリを公開したのだが、自称世界最速と豪語したくせに、本当にそう名乗れるだけの性能があるのか計測したことがなかったので、ベンチマークを行うことにした。私の知る限りこの手のC++ライブラリで最速なのはExprTkなのだが、私が適当に比較をしてみた限りではADAPT-FMPはExprTkよりもわずかに速かった。これをもう少しきちんと測定してみようという試みである。
ADAPT-FMPはベクトルや行列の計算に対応しているがExprTkはしていない、ExprTkはforやwhileのループなどややこしい計算を行えるがFMPは無理、など機能面での差が大きいので、今回は一般的な数値型の計算に絞って行った。

方法

計20種の数式をそれぞれ8,000,000回計算し、10回の平均計算時間を比較した。式はグラフに書かれているとおりである。なお、FMPとExprTkとで同じ意味の式を計算させてはいるが、一部式の表現が異なる。より良い関数が定義されていたり、関数名が異なったりするためだ。例えばFMPでは、"x^2"と書くよりも"square(x)"と書くほうが速いが、ExprTkでは"square"という関数は定義されていない。自然対数はFMPでは"ln"だが、ExprTkでは"log"だ。このあたりを調整している。

結果

f:id:thayakawa:20210119173657p:plain
ベンチマーク結果比較
どの式も大体似たような速度だ。FMPが全体的に勝っているように見えるが、実行時間が小さく目立たない四則演算中心の式ではちょくちょく負けている。大まかに言って、ExprTkは四則演算が3個くらい並んだ場合に強く、FMPは整数変数の冪乗と入り組んだ関数に強い。一部極端にFMPが速いのは、ExprTkは整数変数の冪乗をstd::powでしか計算できないのに対して、FMPは整数と浮動小数点を識別できるため高速な冪乗関数を呼び出せることが理由だ。逆にFMPはsquareやcubeなどの関数でごまかせない整数定数の冪乗に弱い。ExprTkにボロ負けしている。

結論

ベンチマークなんて計算させる式を作為的に自分に有利なように改変することも出来てしまうので、上の結果はあくまで目安でしかないのだが、ExprTkに対して速度でも張り合えることは確からしい。世界最速を主張しても然程不自然でないことは示せただろうか。もっとも、より複雑な使い方に関してはExprTkもFMPも共に独自の機能を持つので、どちらが優れているというわけでもない。

そもそもFMPの最も大きな特徴は上述のように、整数、浮動小数点に加え、文字列、ベクトル、行列の計算に対応しつつ高速である点だが、大多数の数式パーサーは整数と浮動小数点くらいしか使えないので、ベンチ比較のしようがない1。そういう意味ではExprTkとの比較なんて私にとって大した意味はないのだが、似たような使い方ができる以上、対外的にパフォーマンスの利点を主張するのならある程度の比較はしたほうが良かろう、と考えた次第である。特に大学内ではソフトウェアの何たるかを理解できない、速度至上主義の阿呆共が犇めいているので2、あれを黙らせるには目に見えやすい数値があったほうが良いのだ。
FMPを作成してから一年が経過したが、未だADAPT本体への組み込みは実現していない。本業の方が忙しいためだ。このまま風化しないことを祈るばかりである。


  1. そもそも現存する高速な数式パーサーがいずれも単純な浮動小数点型しか扱えなかったことが、FMPの開発を強いられた大きな理由である。

  2. 速度の重要性を否定するわけではないが、速度以外にも重要な点(汎用性とか拡張性とか使いやすさとか)があることを彼らは理解できないのである。困ったちゃんどもめ。