Let's start Scheme

2012-06-14

bytevector->integer

かなりの頻度でこの手続きを使うなぁと思い、適当にパフォーマンスを計測。
100バイトのbytevectorを100000回ほど変換してみた。

コード:
(import (time) (sagittarius control))
(define bv (do ((i 0 (+ i 1)) (bv (make-bytevector 100 0)))
        ((= i 100) bv)
      (bytevector-u8-set! bv i i)))
(define count 100000)
(time (dotimes (i count)
 (bytevector->integer bv)))
結果。
% sash test1.scm

;;  3.245882 real    4.336000 user    0.453000 sys
高速ではないね。現状の実装では、与えられたbytevectorを地味にビットシフトして足しているので、値がbignumになると余計なアロケーションが走る。せっかくC側で実装しているのだし、ちょっと最適化。
与えられたbytevectorのサイズを見ればfixnumの範囲なのか、bignumが必要なのかは分かる。また、どれだけのサイズのbignumが必要なのかも分かる。ということで、その辺を考慮してゴリゴリと書き換えた。
結果として、メモリのアロケーションはbignum作成時のみの最大1回に抑えられている。どれほどパフォーマンスに影響を与えるか試してみた。コードは同じもの。
結果。
% ./build/sash test1.scm

;;  0.027005 real    0.015000 user    0.000000 sys
圧倒的じゃないか、わが軍は。(違ったっけ?)

これでcrypto周りのスピードが改善される(はず)。

No comments:

Post a Comment