我有一个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
了,但是对于多种操作而言,似乎比纯过滤更好。
答案 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>替换为原始类型,例如使用IntArray
或LongArray
(您可以将两个Int
编码为一个Long
。但是,请先配置现有代码