【问题标题】:ClojureScript map lookup slowClojureScript 地图查找速度慢
【发布时间】:2013-05-20 01:11:24
【问题描述】:

我有一张简单的地图:

(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 中运行它。

【问题讨论】:

  • 是的,Firefox 在 ClojureScript 性能方面有点落后。希望我们能尽快向 Mozilla 提交基准代码以帮助解决这个问题。浏览器 REPL 生成的 JavaScript 代码没有完全优化,因为这妨碍了开发。因此,为了真正衡量 ClojureScript 的性能,您需要使用高级编译。

标签: clojure clojurescript


【解决方案1】:

在我的机器上,在我的 1.7ghz Macbook Air 上运行带有高级编译的确切示例大约需要 14 毫秒,该 Macbook Air 运行的是从源代码构建的相对较新的 v8。

为了确保我们对我们认为我们在进行基准测试的内容进行基准测试,最好编写如下内容:

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

在我的机器上,对于 Clojure JVM,这需要大约 70 毫秒。 ClojureScript 运行大约 3600 毫秒,因此慢了大约 50 倍。为什么?这是因为我们默认使用 PersistentArrayMap,而 Clojure 在定义具有复杂键的小型散列映射时不会这样做。

如果我们这样定义 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 倍。

【讨论】:

  • 谢谢 dnolen!请参阅更新以了解更多详细信息以了解差异。看起来我现在只需要切换到 Chromium ;) 并在此处使用您的建议来使用 Hash vs. Array - 很高兴知道这一点。
猜你喜欢
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2015-01-16
  • 2011-10-04
相关资源
最近更新 更多