16

Clojure 有一个数组映射和哈希映射,我无法弄清楚两者之间的区别。如果可能的话,任何人都可以举例说明何时使用它们中的任何一个吗?

4

2 回答 2

15

array-maps 保留插入顺序,但您不应该依赖该行为,除非您知道地图不会被修改的非常简单的情况。如果您确实需要此行为,请使用有序集合。

数组映射应该用于非常小的映射(目前 8 个键),因为查找和“修改”性能优于相同大小的哈希映射:

(def arraymap (array-map :f 1 :g 2 :h 4 :y 5 :w 4))     
(def hashmap (hash-map :f 1 :g 2 :h 4 :y 5 :w 4))
 
(defn add-2-keys [m]
  (assoc m :new 2 :w 4))

(defn access-all-keys [m]
  (mapv m [:f :g :h :y :w :not-there]))

(use 'criterium.core)

; Modification 
(bench (add-2-keys array map))
Execution time mean : 125.640082 ns    
(bench (add-2-keys hashmap))
Execution time mean : 150.918197 ns

; Access
(bench (access-all-keys arraymap))
Execution time mean : 260.547035 ns
(bench (access-all-keys hashmap))
Execution time mean : 305.350156 ns
于 2014-09-26T08:45:32.410 回答
11

数组映射和哈希映射具有相同的接口,但数组映射具有O(N)查找复杂性(即,它实现为一个简单的条目数组),而哈希映射具有O(1)查找复杂性。

数组映射具有维护插入顺序的优势(大多数情况下您不需要),因此当您执行任何迭代映射的操作(例如,mapreduce)时,您可以按照与当你插入它们时。

请注意,如果您反复“修改”(在持久集合的意义上)一个数组映射,在某些时候它将变成一个哈希映射。例如

user=> (type (apply assoc (array-map) (zipmap (range 10) (range 10))))
clojure.lang.PersistentArrayMap
user=> (type (apply assoc (array-map) (zipmap (range 100) (range 100))))
clojure.lang.PersistentHashMap

基本上,如果您不关心键顺序,总是更喜欢哈希映射。此外,如果您确实使用数组映射,请记住查找性能权衡。

于 2014-09-26T01:13:57.150 回答