Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无序对的良好Clojure表示?_Clojure_Set - Fatal编程技术网

无序对的良好Clojure表示?

无序对的良好Clojure表示?,clojure,set,Clojure,Set,我正在创建无序的数据元素对。@Chouser对此的评论说,哈希集的实现是每个节点有32个子集,而排序集的实现是每个节点有2个子集。这是否意味着,如果我使用排序集而不是散列集(假设数据元素具有可比性,即可以排序)来实现这些对,它们将占用更少的空间?(我怀疑这在实践中对我来说很重要。我只有几百对这样的对,在两元素数据结构中查找,甚至在向量或列表中顺序查找,应该很快。但我很好奇。)当比较显式查找列表的前两个元素时,对于使用Clojure的内置集,在运行1000万次时,我看不出有什么显著区别: user

我正在创建无序的数据元素对。@Chouser对此的评论说,哈希集的实现是每个节点有32个子集,而排序集的实现是每个节点有2个子集。这是否意味着,如果我使用排序集而不是散列集(假设数据元素具有可比性,即可以排序)来实现这些对,它们将占用更少的空间?(我怀疑这在实践中对我来说很重要。我只有几百对这样的对,在两元素数据结构中查找,甚至在向量或列表中顺序查找,应该很快。但我很好奇。)

当比较显式查找列表的前两个元素时,对于使用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

当然,像这样的微观基准本身就有缺陷,很难真正做好,所以不要试图用它来证明一个比另一个更好。我只想证明它们非常相似

当显式比较查看列表的前两个元素与使用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}
,和