Skip to content

Instantly share code, notes, and snippets.

@syou6162
Last active October 19, 2017 01:58
Show Gist options
  • Save syou6162/5682330 to your computer and use it in GitHub Desktop.
Save syou6162/5682330 to your computer and use it in GitHub Desktop.
Clojure performance tips

メモリ

個人的にはコレクションと配列との使用メモリ量比較が参考になりました.1M 個の long を格納するとして,vector だと 30MB, vector-of だと 9MB, 配列だと 8MB というのは覚えておいて損は無さそうです.案外 vector はメモリを食いません.

メモリ消費量を測定する用のマクロ

(defn current-total-memory-usage []
  (System/gc)
  (- (.. Runtime getRuntime totalMemory)
     (.. Runtime getRuntime freeMemory)))

(defmacro memory-usage [& exprs]
  `(let [pre# (current-total-memory-usage)]
     ~@exprs
     (double (/ (- (current-total-memory-usage) pre#) 1024))))

速度

type hints

type hintsが足りていないものをlein checkで教えてくれるようにするために、project.cljに以下を追加しておくとよい。

  :global-vars {*warn-on-reflection* true}

なお、マクロの中でtype hintsが付けにくい、などの場合はtype hintsの部分のみを取り出した補助関数を作成するとよい。

補助マクロ

clojure.core/timeの出力が分かりにくいにので、人間にとって分かりやすいフォーマットで出力するマクロを書いてみた。

(defn conv-time-to-easily-understandable-time-format
  "(-> (+ 83.0 (* 5 60 60)) conv-time-to-easily-understandable-time-format)
  => 5 hours 1 minutes 23.000 seconds"
  [t]
  (let [[hour r0] ((juxt quot rem) t (* 60 60))
        [minute r1] ((juxt quot rem) r0 (* 60))]
    (->> [(int hour) "hours"
          (int minute) "minutes"
          (format "%3.3f" r1) "seconds"]
         (interpose \space)
         (apply str))))

(defmacro easily-understandable-time
  "(easily-understandable-time (Thread/sleep 1000))
  \"Elapsed time: 0 hours 0 minutes 1.001 seconds\"
  nil"
  [expr]
  `(let [start# (. System (nanoTime))
         ret# ~expr
         result# (/ (double (- (. System (nanoTime)) start#)) 1000000.0)]
     (->> (/ result# 1000)
          (conv-time-to-easily-understandable-time-format)
          (str "Elapsed time: ")
          (prn))
     ret#))

可変長引数

何度も呼び出される関数などで可変長引数を利用していると速度が遅くなる場合がある。引数が4、5個くらいであればそれぞれ展開したものを用意しておくと速度が改善される場合がある。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment