代码之家  ›  专栏  ›  技术社区  ›  nha

为什么'doall'不强制对序列进行计数?

  •  0
  • nha  · 技术社区  · 8 年前
    (counted? (map identity (range 100)))                  ;; false, expected 
    (time (counted?  (doall  (map identity (range 100))))) ;; false, unexpected
    (time (counted? (into '() (map identity (range 100))))) ;; true, expected - but slower
    

    "1.8.0" )

    第一个结果预计自 map

    doall 整个序列已经实现,现在在内存中。既然实现可能无论如何都要遍历列表,为什么不计算呢?

    第三个是解决方法。它是地道的吗?有其他选择吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Scott    8 年前

    听起来你已经知道懒惰序列不是 counted? .

    然而,在你的例子中 doall 那个 结果作为 LazySeq .看看这个REPL输出:

    user=> (class (doall (map identity (range 100))))
    clojure.lang.LazySeq
    

    into 进入 速度较慢,但对我来说似乎仍然可以接受。

    尽管如此,您也许可以通过调用 vec 根据您的结果,而不是

    user=> (time (counted? (into '() (map identity (range 100)))))
    "Elapsed time: 0.287542 msecs"
    true
    user=> (time (counted? (vec (map identity (range 100)))))
    "Elapsed time: 0.169342 msecs"
    true
    

    更新/更正:

    评论人士恭敬地指出:

    1) time

    2) (vec x) (list x) ; (列表x) 无论x的内容是什么,都是一个恒定的时间操作。

    道尔 返回其输入作为其输出;如果你传入一个LazySeq,你会得到一个LazySeq;如果你传入一个map,你会得到一个map,等等。

    推荐文章