无序对的良好Clojure表示?
我正在创建无序的数据元素对。@Chouser对此的评论说,哈希集的实现是每个节点有32个子集,而排序集的实现是每个节点有2个子集。这是否意味着,如果我使用排序集而不是散列集(假设数据元素具有可比性,即可以排序)来实现这些对,它们将占用更少的空间?(我怀疑这在实践中对我来说很重要。我只有几百对这样的对,在两元素数据结构中查找,甚至在向量或列表中顺序查找,应该很快。但我很好奇。)当比较显式查找列表的前两个元素时,对于使用Clojure的内置集,在运行1000万次时,我看不出有什么显著区别:无序对的良好Clojure表示?,clojure,set,Clojure,Set,我正在创建无序的数据元素对。@Chouser对此的评论说,哈希集的实现是每个节点有32个子集,而排序集的实现是每个节点有2个子集。这是否意味着,如果我使用排序集而不是散列集(假设数据元素具有可比性,即可以排序)来实现这些对,它们将占用更少的空间?(我怀疑这在实践中对我来说很重要。我只有几百对这样的对,在两元素数据结构中查找,甚至在向量或列表中顺序查找,应该很快。但我很好奇。)当比较显式查找列表的前两个元素时,对于使用Clojure的内置集,在运行1000万次时,我看不出有什么显著区别: user
user> (defn my-lookup [key pair]
(condp = key
(first pair) true
(second pair) true false))
#'user/my-lookup
user> (time (let [data `(1 2)]
(dotimes [x 10000000] (my-lookup (rand-nth [1 2]) data ))))
"Elapsed time: 906.408176 msecs"
nil
user> (time (let [data #{1 2}]
(dotimes [x 10000000] (contains? data (rand-nth [1 2])))))
"Elapsed time: 1125.992105 msecs"
nil
当然,像这样的微观基准本身就有缺陷,很难真正做好,所以不要试图用它来证明一个比另一个更好。我只想证明它们非常相似 当显式比较查看列表的前两个元素与使用Clojure的内置集时,我看不出在运行1000万次时有什么显著差异:
user> (defn my-lookup [key pair]
(condp = key
(first pair) true
(second pair) true false))
#'user/my-lookup
user> (time (let [data `(1 2)]
(dotimes [x 10000000] (my-lookup (rand-nth [1 2]) data ))))
"Elapsed time: 906.408176 msecs"
nil
user> (time (let [data #{1 2}]
(dotimes [x 10000000] (contains? data (rand-nth [1 2])))))
"Elapsed time: 1125.992105 msecs"
nil
当然,像这样的微观基准本身就有缺陷,很难真正做好,所以不要试图用它来证明一个比另一个更好。我只想证明它们非常相似 当显式比较查看列表的前两个元素与使用Clojure的内置集时,我看不出在运行1000万次时有什么显著差异:
user> (defn my-lookup [key pair]
(condp = key
(first pair) true
(second pair) true false))
#'user/my-lookup
user> (time (let [data `(1 2)]
(dotimes [x 10000000] (my-lookup (rand-nth [1 2]) data ))))
"Elapsed time: 906.408176 msecs"
nil
user> (time (let [data #{1 2}]
(dotimes [x 10000000] (contains? data (rand-nth [1 2])))))
"Elapsed time: 1125.992105 msecs"
nil
当然,像这样的微观基准本身就有缺陷,很难真正做好,所以不要试图用它来证明一个比另一个更好。我只想证明它们非常相似 当显式比较查看列表的前两个元素与使用Clojure的内置集时,我看不出在运行1000万次时有什么显著差异:
user> (defn my-lookup [key pair]
(condp = key
(first pair) true
(second pair) true false))
#'user/my-lookup
user> (time (let [data `(1 2)]
(dotimes [x 10000000] (my-lookup (rand-nth [1 2]) data ))))
"Elapsed time: 906.408176 msecs"
nil
user> (time (let [data #{1 2}]
(dotimes [x 10000000] (contains? data (rand-nth [1 2])))))
"Elapsed time: 1125.992105 msecs"
nil
当然,像这样的微观基准本身就有缺陷,很难真正做好,所以不要试图用它来证明一个比另一个更好。我只想证明它们非常相似 如果我在处理无序对,我通常喜欢使用映射,因为这样可以很容易地查找其他元素。例如,如果我的配对是[27],那么我将使用
{27,72}
,我可以做({27,72}2)
,这就给了我7
至于空间,实施实际上非常注重空间。如果查看源代码(请参见上一个链接),您将看到它分配了一个对象[]
,其大小与保存所有键/值对所需的大小相同。我认为这是所有不超过8个键/值对的映射的默认映射类型
这里唯一需要注意的是,您需要小心重复的密钥<代码>{2 2,2 2}将导致异常。您可以通过这样做来解决这个问题:(merge{22}{22})
,即(merge{ab}{ba})
,其中a
和b
可能具有相同的值
以下是我的回复中的一个小片段:
user=> (def a (array-map 1 2 3 4))
#'user/a
user=> (type a)
clojure.lang.PersistentArrayMap
user=> (.count a) ; count simply returns array.length/2 of the internal Object[]
2
注意,我在上面显式地调用了
数组映射。这与我刚才问的一个问题有关,这个问题与repl:中的map文本和def
有关。如果我使用无序对进行操作,我通常喜欢使用map,因为这样可以方便地查找其他元素。例如,如果我的配对是[27],那么我将使用{27,72}
,我可以做({27,72}2)
,这就给了我7
至于空间,实施实际上非常注重空间。如果查看源代码(请参见上一个链接),您将看到它分配了一个对象[]
,其大小与保存所有键/值对所需的大小相同。我认为这是所有不超过8个键/值对的映射的默认映射类型
这里唯一需要注意的是,您需要小心重复的密钥<代码>{2 2,2 2}
将导致异常。您可以通过这样做来解决这个问题:(merge{22}{22})
,即(merge{ab}{ba})
,其中a
和b
可能具有相同的值
以下是我的回复中的一个小片段:
user=> (def a (array-map 1 2 3 4))
#'user/a
user=> (type a)
clojure.lang.PersistentArrayMap
user=> (.count a) ; count simply returns array.length/2 of the internal Object[]
2
注意,我在上面显式地调用了
数组映射。这与我刚才问的一个问题有关,这个问题与repl:中的map文本和def
有关。如果我使用无序对进行操作,我通常喜欢使用map,因为这样可以方便地查找其他元素。例如,如果我的配对是[27],那么我将使用{27,72}
,我可以做({27,72}2)
,这就给了我7
至于空间,实施实际上非常注重空间。如果查看源代码(请参见上一个链接),您将看到它分配了一个对象[]
,其大小与保存所有键/值对所需的大小相同。我认为这是所有不超过8个键/值对的映射的默认映射类型
这里唯一需要注意的是,您需要小心重复的密钥<代码>{2 2,2 2}
将导致异常。您可以通过这样做来解决这个问题:(merge{22}{22})
,即(merge{ab}{ba})
,其中a
和b
可能具有相同的值
以下是我的回复中的一个小片段:
user=> (def a (array-map 1 2 3 4))
#'user/a
user=> (type a)
clojure.lang.PersistentArrayMap
user=> (.count a) ; count simply returns array.length/2 of the internal Object[]
2
注意,我在上面显式地调用了
数组映射。这与我刚才问的一个问题有关,这个问题与repl:中的map文本和def
有关。如果我使用无序对进行操作,我通常喜欢使用map,因为这样可以方便地查找其他元素。例如,如果我的配对是[27],那么我将使用{27,72}
,和