Mir*_*lov 15 vector clojure sequence
我有以下代码,它增加了向量中每对的第一个元素:
(vec (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
Run Code Online (Sandbox Code Playgroud)
但是我担心这个代码不够优雅,因为它首先使用map创建一个序列,然后将其转换回矢量.
考虑这个类比:
(into [] (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
Run Code Online (Sandbox Code Playgroud)
在#clojure@irc.freenode.net上有人告诉我,使用上面的代码是不好的,因为into扩展到了(reduce conj [] (map-indexed ...)),在这个过程中产生了许多中间对象.然后我被告知实际上into并没有扩展到(reduce conj ...)可能的时候使用瞬态.同时测量经过的时间显示into实际上比...更快vec.
所以我的问题是:
map矢量的正确方法是什么?vec和into向量时,下面会发生什么?相关但不重复的问题:
Mic*_*zyk 29
实际上,从Clojure 1.4.0开始,这样做的首选方法是使用mapv,就像map它的返回值是一个向量一样.它是迄今为止最有效的方法,根本没有不必要的中间分配.
Clojure的1.5.0将带来一个新的减速机库,将提供一个通用的方法map,filter,take,drop等,同时创造载体,具有可用into [].您可以在1.5.0 alphas和最近的ClojureScript标记版本中使用它.
至于(vec some-seq)和(into [] some-seq),第一个最终委托一个Java循环注入some-seq一个空的瞬态向量,而第二个在非常有效的Clojure代码中做同样的事情.在这两种情况下,都需要进行一些初始检查,以确定在构造最终返回值时采用哪种方法.
vec并且into []对于小长度(最多32个)的Java数组有显着不同 - 第一个将对数组进行别名(使用它作为新创建的向量的尾部)并要求不随后修改数组,以免数据的内容向量变化(参见docstring); 后者创建一个带有新尾部的新向量,而不关心将来对阵列的更改.