toge's diary

コンピュータ関連の趣味をつらつらと。

ExprEvalの導入 -C言語から定数・変数の操作 高速版-

今まで定数・変数の追加・操作をやってきましたが、実はもっと高速に操作する方法があったりします。
それが本家ではFast Variable Accessという機能です。
これはexprValListAdd()を使わずに値の更新を、exprValListGet()を使わずに値の参照を行って、処理を高速化・直感的にするものです。

まあ、早い話しが、変数リストに格納されている各変数のアドレスを直接返して、そのアドレスに対しての操作をやって貰うというものです。
一度変数リストから変数のアドレスを取得出来ればあとはやりたい放題というわけです。

マニュアルによるとFast Variable Accessを使うためにはマクロEXPR_FAST_VAR_ACCESSを定義しなければいけないそうですが、現在のソースコード(ExprEval1.6)にはEXPR_FAST_VAR_ACCESSを使っている部分が一箇所もないので、将来的なことを考えての処置なんでしょうね。
とりあえず現状ではexpreva.hの冒頭でEXPR_FAST_VAR_ACCESSが定義されているので、気にしないで普通にコンパイルしていればよさそうです。

さて使用方法ですが、いたって簡単です。

  1. exprValListAdd()なりで変数・定数を作成する
  2. exprValListGetAddress()で変数のアドレスを取得する
  3. 変数のアドレスを直接操作する
  4. exprEval()で式オブジェクトを評価する

といった手順になります。exprValListGetAddress()はexprValListGet()と同じで存在しない変数を取得しようとすると、変数を作成したりはせず、処理を停止してしまいます。

exprValListGetAddress()の使い方は、殆どexprValListGet()と同じです。唯一違うのは第3引数がEXPRTYPEのポインタのポインタになっていることだけです。ここに指定した変数のアドレスが入ることになります。

 EXPRTYPE *testVar;
 exprValListGetAddress(v, "testVar", &testVar);  

 *testVar = 5.0;
 printf("testVar = %f\n", *testVar);

今まで作ってきた値を操作するサンプル、sample04.cと値を取得するサンプル、sample06.cを書き直してたものを置いておきます。
http://toge.skr.jp/program/expreval/sample07.c
http://toge.skr.jp/program/expreval/sample08.c

最後にベンチマークを取ろうと思ったのですが・・・、やめておきます。
毎回変数リストの中を検索している従来の方式より、ポインタ操作だけの方が圧倒的に速いのが常識的にわかってしまいますから。

変数・定数の操作関係はひとまずこれで終わりです。次回はユーザー定義の関数を追加する方法を調べます。