加快Kotlin中大型列表的过滤器

时间:2019-02-09 19:44:26

标签: optimization kotlin

我有一个ArrayList,大约有4000 Pair<Int,Int> s(网格上的点)。 在某一点上,我需要获取在x和y坐标的特定范围内的点。

到目前为止,我的代码是:

val points: ArrayList = // ...

val xRange: IntRange = x: Int - spacingX: Int .. x: Int + spacingX: Int
val yRange: IntRange = y: Int - spacingY: Int .. y: Int + spacingY: Int

val nearPoints: ArrayList<Point<Int, Int>> = points.filter { xRange.contains(it.first) && yRange.contains(it.second) }

这比遍历整个列表要快得多,但我希望进一步加快这一过程。

是否可以通过另一种结构更快地获得nearPoints: ArrayList?我已经读过Sequence了,但是对于多种操作而言,似乎比纯过滤更好。

2 个答案:

答案 0 :(得分:1)

使用ArrayList可以保证迭代时恒定的时间复杂度O(1)(每个访问的元素),并且contains的{​​{1}}已经进行了范围检查

IntRange

并且不搜索特定元素,我认为您无法进一步加快其速度。

注意:使用override fun contains(value: Int): Boolean = first <= value && value <= last 代替in会更惯用。

答案 1 :(得分:1)

科特林(Kotlin)中的sequence使该过程变得懒惰。在JVM级别,您将拥有一个类似Iterable的类,该类将使用ArrayList中的Iterator来应用过滤器。

最好是在真实数据上分析代码(但是4000个项目可能根本不多),并查看瓶颈在哪里。

您需要将这些点放入ArrayList中。这意味着您根本不需要懒惰。我投票使用ArrayList上的.filter { .. } inline 函数。在这种情况下,lambda内联到代码中,每个元素没有方法调用。检查字节码。也许,您甚至可以用比较代替Ranges。

是否需要更高的速度-您可以尝试将ArrayList>替换为原始类型,例如使用IntArrayLongArray(您可以将两个Int编码为一个Long。但是,请先配置现有代码