Clojure:序列返回到向量

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (31)

如何在序列生成操作(如排序)之后将序列转换回向量?在向量序列上使用(vec.)是否代价高昂?

一种可能性是创造一个新的向量的顺序:

(vec (sort [1 2 3 4 5 6]))

我之所以问这个问题,是因为我需要对大型排序向量的随机访问(n.)-它们现在是继排序之后的巨大序列,具有可怕的O(N)随机访问时间。

提问于
用户回答回答于

从我自己的测试中,如果需要进行大量排序,可能会更好地直接处理数组。但是,如果你很少排序,并且有很多随机访问,那么使用向量可能是一个更好的选择,因为随机访问时间平均要快40%以上,但是由于将向量转换为数组,然后返回到向量,排序性能非常糟糕。以下是我的发现:

(def foo (int-array (range 1000)))

(time
  (dotimes [_ 10000]
    (java.util.Arrays/sort foo)))

; Elapsed time: 652.185436 msecs

(time
  (dotimes [_ 10000]
    (nth foo (rand-int 1000))))

; Elapsed time: 7.900073 msecs

(def bar (vec (range 1000)))

(time
  (dotimes [_ 10000]
    (vec (sort bar))))

; Elapsed time: 2810.877103 msecs

(time
  (dotimes [_ 10000]
    (nth bar (rand-int 1000))))

; Elapsed time: 5.500802 msecs
用户回答回答于

Clojure小组上发布了一个解决方案。

(defn sorted-vec
  [coll]
  (let [arr (into-array coll)]
    (java.util.Arrays/sort arr)
    (vec arr)))

Clojure's sort在一个有序数组中返回一个seq; 这种方法可以做同样的事情,但是会返回一个向量,而不是seq。

如果你愿意,你甚至可以跳过转换回Clojure持久数据结构:

(defn sorted-arr
  "Returns a *mutable* array!"
  [coll]
  (doto (into-array coll)]
    (java.util.Arrays/sort))

但由此产生的Java数组(在大多数情况下您可以将其视为Clojure集合)将是可变的。如果你不把它交给其他代码,那很好,但要小心。

所属标签

可能回答问题的人

  • 嗨喽你好

    7 粉丝480 提问9 回答
  • uncle_light

    5 粉丝518 提问8 回答
  • 富有想象力的人

    3 粉丝0 提问7 回答
  • 无聊至极

    4 粉丝504 提问6 回答

扫码关注云+社区

领取腾讯云代金券