与えられた入力コレクションのnグラムを怠惰なseqとして返す関数を実装しました。Clojureで怠惰なseqを生成する非線形の減速
(defn gen-ngrams
[n coll]
(if (>= (count coll) n)
(lazy-seq (cons (take n coll) (gen-ngrams n (rest coll))))))
この関数を大きな入力コレクションで呼び出すと、実行時間が直線的に増加することが予想されます。しかし、私が観察するタイミングはそれよりも悪いです:
user> (time (count (gen-ngrams 3 (take 1000 corpus))))
"Elapsed time: 59.426 msecs"
998
user> (time (count (gen-ngrams 3 (take 10000 corpus))))
"Elapsed time: 5863.971 msecs"
9998
user> (time (count (gen-ngrams 3 (take 20000 corpus))))
"Elapsed time: 23584.226 msecs"
19998
user> (time (count (gen-ngrams 3 (take 30000 corpus))))
"Elapsed time: 54905.999 msecs"
29998
user> (time (count (gen-ngrams 3 (take 40000 corpus))))
"Elapsed time: 100978.962 msecs"
39998
corpus
は、文字列トークンのCons
です。
この動作の原因とは何ですか?パフォーマンスを向上させるにはどうすればよいですか。