https://github.com/ksss/digest-murmurhash
昨日出したv0.0.1に引き続き改良を加え、v0.1.0をリリースしました。 変更点は以下
- bench用スクリプト添付
- メモリ管理を自前で実装
to_i
メソッドの追加
bench用スクリプト添付
前回で5%しか速度が上昇しないという苦い思いをしたのですが、これはおかしいとちゃんとしたスクリプトを書いてみたところ測定に使ったRubyで書いたMurmurHashがバグってました。
これはいかんと思ってbench用スクリプトを作成。Ruby版とC版で長さ40のランダム文字列を10000種用意して全部を同ロジックで実行して速度比を出したところ、およそ15倍早くなってました。まあこれぐらいは期待通り。
やはり単純な数値計算が多い場合はC拡張が効きます。
メモリ管理を自前で実装
さらに文字列の保持をRubyオブジェクトに丸投げしていたのでこれもCで書き換え。メモリの確保回数もできるだけ減らすように最初64byte確保し、超えそうならその2倍確保、更に超えそうなら2倍(合計4倍)確保……とAsciiPackと同じ方法をとっています。reset
してもメモリは開放せずそのままヒープを再利用します。
Ruby文字列のメモリ確保戦略はまだ知らないのですが、少なくとも文字列同士を連結させるメソッド呼び出しを削減。これもbench用スクリプトにかけるとRuby版の24倍早くなりました。
to_i
メソッドの追加
to_i
メソッドは継承元のDigest::Baseでは存在しないのですが、MurmurHashの使われ方として「いい感じに散らばるよう文字列を数値化する」ことが目的とされやすいです。そもそも元の情報を桁あふれで失ってしまっているのでセキュリティ目的には使われないでしょう。
となれば毎回
@murmur.hexdigest.to_i(16)
なんてするのは電気代の無駄です。
@murmur.to_i
こんな感じで書ければエコでいい感じ。
でもチキンなので
Digest::MurmurHash.to_i(string)
とはしていません。
to_iは主語がMurmurHashでオプションがstring???みたいに感じ、名前として変な感じがするからです。 もう少しいい名前が思いついたらクラスメソッドに追加してしまおうと思います。自分で使うためにね。