我有一个Clojure程序,它使用一些大型地图(1000 - 2000项),每秒访问30到40次,并使用字符串作为键。我想知道如果我使用关键字或符号代替键是否会有很大的性能差异呢?
答案 0 :(得分:17)
Clojure地图查找速度非常快,并不特别依赖于地图的大小。
事实上,它们几乎与纯Java HashMaps一样快,同时享有许多优于传统HashMaps的优势,包括不可变和线程安全。
如果您每秒只进行30-40次查询,那么我保证您将永远不会注意到差异,无论您使用什么作为键。担心这会被视为过早优化。
让我们证明一下:以下代码使用字符串作为键进行了一百万次地图查找:
(def str-keys (map str (range 1000)))
(def m (zipmap str-keys (range 1000)))
(time (dotimes [i 1000] (doseq [k str-keys] (m k))))
=> "Elapsed time: 69.082224 msecs"
以下使用关键字作为键进行了一百万次地图查找:
(def kw-keys (map #(keyword (str %)) (range 1000)))
(def m (zipmap kw-keys (range 1000)))
(time (dotimes [i 1000] (doseq [k kw-keys] (m k))))
=> "Elapsed time: 59.212864 msecs"
对于符号:
(def sym-keys (map #(symbol (str %)) (range 1000)))
(def m (zipmap sym-keys (range 1000)))
(time (dotimes [i 1000] (doseq [k sym-keys] (m k))))
=> "Elapsed time: 61.590925 msecs"
在我的测试中,符号和关键字比字符串略快,但仍然可以通过统计错误轻松解释差异,并且对于所有情况,每次查找的平均执行时间小于100 纳秒 。
所以你的30-40次查找可能占你的CPU时间的0.001%(这甚至允许在真实应用程序中,由于缓存问题,查找可能会慢几倍)
关键字特别是稍微快一点的可能原因是它们被实习(因此可以使用引用相等来检查相等性)。但是你可以看到差异足够小,你真的不需要担心它。