日曜プログラミング

休日趣味でやってるプログラミング関連記事をダラダラと

On Lisp -> Clojure へ移植: 12.1~12.3

ここでも一応書いておくが、前の 11 章はベースになる setf に該当するものが Clojure には見当たらないので章全体を飛ばしている。

また、この章のサンプル移植は most-of しかなく、殆ど無いも同然なので ここも飛ばしてもらっても構わない。

12.1 新しいユーティリティ

p112

図68 most-of の関数版とマクロ版、を書きたかったのだが、 破壊的変更を伴う incf は仮に定義しても Clojure と相性が悪すぎるので 変わりに loop 版を書いてみた。

(defn most-of [& args]
  (let [all (count args)]
    (>
     (count (filter (complement nil?) args))
     (/ all 2))))

(defn most-of [& args]
  (let [needs (Math/floor (/ (count args) 2))]
    (loop [hits 0
           a args]
      (if (> hits needs)
        true
        (if (seq a)
          (recur (if (first a) (inc hits) hits)
                 (rest a)))))))

で、ここでベンチマークライブラリ criterium を使って比較してみる。

上の通常関数版。

(bench (most-of :t :t :t nil))
;Evaluation count : 49568880 in 60 samples of 826148 calls.
;             Execution time mean : 1.198932 μs
;    Execution time std-deviation : 12.024127 ns
;   Execution time lower quantile : 1.180818 μs ( 2.5%)
;   Execution time upper quantile : 1.228185 μs (97.5%)
;                   Overhead used : 11.322126 ns
;
;Found 3 outliers in 60 samples (5.0000 %)
;  low-severe   3 (5.0000 %)
; Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
;nil

loop 版。

(bench (most-of :t :t :t nil))
;Evaluation count : 143876640 in 60 samples of 2397944 calls.
;             Execution time mean : 412.751676 ns
;    Execution time std-deviation : 10.560372 ns
;   Execution time lower quantile : 402.826633 ns ( 2.5%)
;   Execution time upper quantile : 440.581697 ns (97.5%)
;                   Overhead used : 11.322126 ns
;
;Found 8 outliers in 60 samples (13.3333 %)
;  low-severe   3 (5.0000 %)
;  low-mild     5 (8.3333 %)
; Variance from outliers : 12.6261 % Variance is moderately inflated by outliers
;nil

確か loop に書き直す方が速くなるというのはチラホラ見ていたが、 こういうのって作るプログラムの目的や呼び出す回数との兼ね合いだよなあ。

と、本書でもそんな事が書かれてるので次の nthmost は飛ばしますw

12.2 例:B`ezier 曲線

ここもグラフィックを実際に出すまでの具体的手順が分からんので飛ばします。

12.3 応用

この章項目自体には載ってないので次へ。

第 12 章 コンパイル時の計算処理

はここまで。