Clojure 日本語ドキュメントのJavaとの連携 というセクションを読んでて、ああなるほど Clojure に型を推測させるより、もう判ってるなら(コードは少し冗長になるけど)変数の型を予め指定してやったほうが処理は速い。
Clojureは型ヒントを使ってコンパイラを助けることで、パフォーマンスの重要なコード領域に対してリフレクションを避けることができる。
;; 文字列の長さを返す : 型指定なし (defn len [s] (.length s)) ;; 文字列の長さを返す : 型指定あり (defn len-string [^String s] (.length s)) ;; 長い文字列を作る (use '[clojure.string :only (join)]) (def s (join "" (repeat 1000 "a"))) ;; 処理時間を測ってみよう! ;; 型指定なし (time (len s)) "Elapsed time: 0.04 msecs" 1000 ;; 型指定あり (time (len-string s)) "Elapsed time: 0.022 msecs" 1000
とまぁこんな感じで処理時間に差が出る。
それから
ClojureはローカルコンテキストにおけるJavaの基本型を使った高速な計算や算術演算をサポートする。すべてのJava基本型(int, float, long, double, boolean, char, short, byte)がサポートされている。
;; 1 から n まで数え上げるだけの関数 ;; 型指定なし (defn cnt [n] (loop [i 1] (if (< i n) (recur (inc i)) i))) ;; 型指定あり (defn cnt-int [n] (let [n (int n)] (loop [i (int 1)] (if (< i n) (recur (inc i)) i)))) ;; 処理時間を測ってみよう! ;; 型指定なし (time (cnt 1000000)) "Elapsed time: 73.091 msecs" 1000000 ;; 型指定あり (time (cnt-int 1000000)) "Elapsed time: 3.322 msecs" 1000000