繁体   English   中英

如何在Clojure中快速删除向量中的元素?

[英]How to remove elements from a vector in a fast way in Clojure?

我正在尝试从Clojure向量中删除元素:

请注意,我正在使用Kotlin的Clojure运算

val set = PersistentHashSet.create("foo")
val vec = PersistentVector.create("foo", "bar")
val seq = clojure.`core$remove`.invokeStatic(set, vec) as ISeq
val resultVec = clojure.`core$vec`.invokeStatic(seq) as PersistentVector

这等效于以下Clojure代码:

(remove #{"foo"} ["foo" "bar"])

该代码可以正常工作,但是我注意到从seq创建向量非常慢。 我写了一个基准,结果如下:

| Item count | Remove ms | Remove with converting back to vector ms|
-----------------------------------------------------------------
| 1000       | 51        | 1355                                 |
| 10000      | 71        | 5123                                 |

您知道如何将remove操作产生的seq转换回vector而不会降低性能吗?

如果不可能,是否有其他方法可以执行remove操作?

您尝试做的事情从根本上表现不佳。 向量用于快速索引的读/写,并且O(1)访问右端。 要执行其他任何操作,您必须将向量撕开并重新构建,这是O(N)操作。 如果需要这样的操作才能高效,则必须使用其他数据结构。

您可以尝试执行补充操作以remove返回向量的方法:

(filterv (complement #{"foo"}) 
         ["foo" "bar"])

注意使用filterv v表示从头开始使用向量,并返回向量,因此不需要转换。 它在后台使用了transient矢量,因此它应该非常快。

我使用complement否定谓词,因此可以使用filterv ,因为没有removev 无论如何remove只是被定义为filtercomplement ,因此基本上,这就是您已经在做的事情,只是严格。

为什么不使用PersistentHashSet? 快速删除,尽管没有命令。 我确实隐约记得,Clojure在需要的时候也有一个分类的集合。

在接受remove的惰性结果等同于转换回向量的具体结果时,您犯了一个错误。 (remove ...)的惰性结果与(count (remove ...))隐含的具体结果进行比较。 您会发现它比做(vec (remove ...))慢一些。 同样,对于真正的速度至关重要的应用程序,没有什么比使用本机Java ArrayList

(ns tst.demo.core
  (:require
    [criterium.core :as crit]    )
  (:import [java.util ArrayList]))

(def N 1000)
(def tgt-item (/ N 2))

(def pred-set #{ (long tgt-item) })
(def data-vec (vec (range N)))

(def data-al (ArrayList. data-vec))
(def tgt-items (ArrayList. [tgt-item]))


(println :lazy)
(crit/quick-bench
  (remove pred-set data-vec))

(println :lazy-count)
(crit/quick-bench
  (count (remove pred-set data-vec)))

(println :vec)
(crit/quick-bench
  (vec (remove pred-set data-vec)))

(println :ArrayList)
(crit/quick-bench
  (let [changed? (.removeAll data-al tgt-items)]
    data-al)) 

结果:

:lazy           Evaluation count : 35819946     time mean :    10.856 ns 
:lazy-count     Evaluation count :     8496     time mean : 69941.171 ns 
:vec            Evaluation count :     9492     time mean : 62965.632 ns 
:ArrayList      Evaluation count :   167490     time mean :  3594.586 ns

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM