5

私は簡単な地図を持っています:

(def my-map
  {[1 2 3] 1
   [1 2 4] 5
   [3 4 2] 3
   [4 5 3] 3
   [5 2 5] 6
   [9 2 1] 5
   [8 3 1] 6})

検索を実行するために使用します。ただし、これはパフォーマンスがかなり低下します。

(time (doseq [x (range 500)]
        (my-map [1 2 8])))

"Elapsed time: 170 msecs"

同じマシンで、Clojure は約 236 ミリ秒で 500,000 を実行できます。つまり、約 700 倍高速です。Clojure が ClojureScript よりも高速であることは予想外ではありませんが、ClojureScript がなぜこれほど遅いのか、私は混乱しています。

ClojureScript で効率的かつ読みやすい方法で上記のような単純な多値ルックアップ マップを作成する方法についてのアイデアはありますか? ベクトルキーソリューションを使用する代わりに一連のifs を実行すると、確かに高速に動作することはわかっていますが、もう少し読みやすく/保守しやすいものを見ています。

より多くの情報を更新するだけです。上記は Firefox で行ったので、V8 に比べて遅くなります。以下:

(def my-map2
  (into cljs.core.PersistentHashMap/EMPTY
        {[1 2 3] 1
         [1 2 4] 5
         [3 4 2] 3
         [4 5 3] 3
         [5 2 5] 6
         [9 2 1] 5
         [8 3 1] 6}))

(defn p1 []
  (let [v [1 2 8]]
    (dotimes [_ 5]
      (time (dotimes [_ 500000]
              (get my-map2 v))))))

与えます:

"Elapsed time: 3295 msecs"

"Elapsed time: 3246 msecs"

"Elapsed time: 3113 msecs"

"Elapsed time: 3107 msecs"

"Elapsed time: 3121 msecs"

Chromium バージョン 25.0.1364.160 Ubuntu 13.04 (25.0.1364.160-0ubuntu3)。したがって、ClojureScript では Clojure よりも約 13 倍遅くなりますが、これは以前よりもはるかに優れています。これをブラウザ repl で直接実行していることにも注意してください。

4

1 に答える 1

7

私のマシンでは、高度なコンパイルを使用して正確な例を実行すると、ソースからビルドされた比較的最近の v8 を実行している 1.7 GHz の Macbook Air で約 14 ミリ秒かかります。

ベンチマークしていると思われるものをベンチマークしていることを確認するには、次のように書くのが最善です。

(let [v [1 2 8]]
  (dotimes [_ 5]
    (time
      (dotimes [_ 500000]
        (get my-map v)))))

私のマシンでは、Clojure JVM のマシンで 70 ミリ秒かかります。ClojureScript はこれを約 3600 ミリ秒で実行するため、約 50 倍遅くなります。なんで?これは、Clojure が複雑なキーを持つ小さなハッシュ マップを定義するときに PersistentArrayMap をデフォルトにしないためです。

代わりに my-map を次のように定義するとどうなりますか:

(def my-map
  (into cljs.core.PersistentHashMap/Empty
    [[1 2 3] 1
     [1 2 4] 5
     [3 4 2] 3
     [4 5 3] 3
     [5 2 5] 6
     [9 2 1] 5
     [8 3 1] 6]))

ベンチマークには約 170 ミリ秒かかりますが、これは Clojure JVM からそれほど離れていません。

したがって、Clojure が実装していて、まだ手をつけていない最適化がたくさんあることは間違いありません。それでも、慣用的な Clojure コードの場合、V8 のような高度に調整された JavaScript エンジンで期待できる最善のことは、Clojure JVM の 2 ~ 10 倍であると思います。

于 2013-05-20T22:37:52.093 に答える