SATySFiで文字列を分割する方法の速さを調べてみた

はじめに

SATySFi v0.0.4でstring-explode: string -> int listというプリミティブが追加されました。 これは文字列をユニコードポイントのリストにするもので、これによって文字列の分割や比較が楽になりました。

文字列を一文字ずつのリストにすることは結構ありますが、今まではstring-sub再帰関数を使って分割していましたが、この方法と比べてstring-explodeを使う方法はどれくらい早いのか気になったので調べてみました。

実装はstring-explodeを使う方が簡単なのですが、遅かったら使いにくいので検討してみる価値はあると思います。

実験してみた

実験方法

実装はこのようになっています。

  • string-subを使った実装
let str-to-lst-sub str =
  let str-len = string-length str in
  let-rec sub lst n =
    if n <= 0 then
      lst
    else
      let s = string-sub str (n - 1) 1 in
      sub (s::lst) (n - 1)
  in
  sub [] str-len
  • string-explodeを使った実装
let str-to-lst-explode str =
  str
  |> string-explode
  |> List.map (fun i -> string-unexplode [i])
  • テスト用文書として「吾輩は猫である」の冒頭を分割し再度文字列化するものを2000回繰り返した。A4サイズで1177ページ程度。
  • Windows 10 + Ubuntu on WSL + SATySFI v0.0.4 で比較した。
  • 3 回予備で実行した後、9 回実行して所要時間を計測、その中間にある 5 回分の平均値を求めた。

実験結果

  • string-subを使ったものは24.000秒
  • string-explodeを使ったものは24.507秒

string-explodeを使った方はstring-subを使った方に比べて1.02倍時間がかかる

考察

ほとんど時間が変わらない。string-explodeを使った結果実装が簡単になるならこちらを採用するのも良いかもしれない。

しかし、v0.0.4からなのでそこは気を付けないといけないかもしれない。