『プログラミングErlang』15章本文では
- 単語ごとに分割する
- 単語の両端に空白を付加する
- 3文字ずつ取り出す
という3段階の手順になっている。これを1段階に、すなわち先頭から順番に3文字ずつ抜き出していくアルゴリズムに変更してみた。
-define(NL, $\r,$\n). % 先頭に改行を付加して処理開始 my_scan_trigrams([?NL|_]=L, F, A) -> each_trigram(L, F, A); my_scan_trigrams(L, F, A) -> each_trigram([?NL|L], F, A). each_trigram(L, F, A) -> case L of %% 終端の処理 [?NL] -> A; [?NL, X] -> F([$\s, X, $\s], A); [X, Y] -> F([X, Y, $\s], A); %% 単語の先頭 [?NL, X, ?NL|T] -> each_trigram([?NL |T], F, F([$\s, X, $\s], A)); [?NL, X, Y |T] -> each_trigram([X, Y|T], F, F([$\s, X, Y ], A)); %% 単語の途中 [X, Y, ?NL|T] -> each_trigram([?NL |T], F, F([X, Y, $\s], A)); [X, Y, Z |T] -> each_trigram([Y, Z|T], F, F([X, Y, Z ], A)) end.
微々たる差ではあるが、少しだけ速い。
Counting by my_scan_trigrams - No of trigrams=3357707 time/trigram=0.46476926068891655 Counting by scan_word_list - No of trigrams=3357707 time/trigram=0.5411714006016606