LoginSignup
0
0

More than 5 years have passed since last update.

VBAHaskellの紹介 その9 (明示的なループの性能がいまいち)

Last updated at Posted at 2015-04-30

(この記事ははてなブログ http://mmyymmdd.hatenablog.com/ の再掲です)
2015-04-23

ここでの「明示的なループ」とはVBAコード中のループのことで、VBAHaskellの関数適用関数である applyFun 等を繰り返し呼び出したときの性能が良くない。mapFfoldlなどのリスト処理関数でもループ処理はしているが、それはdllの中で行われているのでこの話とは関係ない。

原因は applyFun の毎回の呼び出しの中で、VBA配列の中にネストされている関数をC++側の構造に展開する過程で最低でも2回は new が走るためである。

典型的に現われるのが、繰り返し処理そのものと言える repeat_while 関数で、サンプルの中では、以下のように円周率を確率的に求めている。

4 * repeat_while (0, _
                  p_equal(0, 0), _
                  p_plus(p_less(p_distance( _
                  p_makePair(p_rnd(0, 1), p_rnd(0, 1)), _
                  Array(0, 0)), 1.0)), _
                  N) _
          / N 

repeat_while を使って以下のことをやっている。

  1. 「区間 [0,1] の一様変数のペアを作り、原点からの距離が1.0未満であれば1を、そうでなければ0を加える」関数をファンクタとして作り、
  2. 0を初期値として、述語 p_equal(0, 0) が満たされている間、
  3. 最大N回繰り返す
  4. 結果を4倍してNで割る

述語 p_equal(0, 0) は要するに 0 = 0 なので恒真式となり、とにかくN回繰り返すわけだが、これが遅い。Core i5マシンでN=10000だと250msくらいかかるのだ。ファンクタは比較的複雑だし、述語の分もある。

lower_bound や upper_bound の中でも同様のことが起きているはずだが、述語の呼出し回数はデータ長の対数比例なので問題ないだろう。

これを改善する方法はいくつかあるはずだが、思いついたものはどれも冴えない感じなので止まっている。

VBAHaskellの紹介 その8 (ソート関連)
VBAHaskellの紹介 その1 (最初はmapF)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0