kotlin - Kotlin:有没有办法把它作为一个序列来迭代?
问题描述
我正在制作一个图像过滤器,我已经完成了这项工作,但我已经读过,对于大型集合,最好使用序列进行迭代,因为是 8k 图像,我想我会因为它而获得一些性能延迟初始化用 aSequence<IntArray>
而不是Array<IntArray>
,甚至Sequence<Sequence<Int>>
. 我不知道这是否可能,我很困惑并试图为我学习这个新范式,而且我很难找到更容易理解这个概念的用法语法的材料。
这是一个尝试过的方法,但是一团糟,我不太了解如何进行此操作,或者即使我也应该使用“newImage”作为序列。
val myPredicate = { array : IntArray -> !array.first() /*???*/ && !array.last() }
image.asSequence().forEach { array ->
array.filter(myPredicate ) // ???
}
这是要转换的功能代码:
fun chunker(image : Array<IntArray>) : Array<IntArray> {
val arrayRowSize = image.size
val arrayColSize = image[0].size
val newImage : Array<IntArray> by lazy {
Array(arrayRowSize) { IntArray(arrayColSize) }
}
var kernel = IntArray(9)
// to translate to a Sequence those two for loops
for (row in 1 .. arrayRowSize - 2) {
for (col in 1 .. arrayColSize - 2) {
kernel = changer(row, col, kernel, image)
newImage[row][col] = kernel[4]
}
}
return newImage
}
解决方案
我已经读过,对于大型集合,最好使用序列进行迭代
您可能读到的是,给定一个类似的功能管道myCollection.filter(...).map(...).first(...)
,使用 a 可以提高性能Sequence
,主要有两个原因:
- 如果不需要,序列将不会处理所有元素(
first()
结尾可能会在看到所有元素之前终止) - 与常规集合不同,该序列不会为每个管道步骤(如过滤器或映射)创建中间集合
在您的情况下,您甚至没有功能操作的管道,并且您不创建中间集合,因为您直接创建和填充结果。此外,您不能提前终止,因为无论如何您都想处理所有像素,所以Sequence
可能是合适的,但在这里不一定是性能改进。
如果您正在编译这个针对 JVM 的 Kotlin 代码,那么您至少可以做一件事来提高性能:
不要使用二维数组,而是使用具有特殊索引的一维数组。更具体地说,newImage[row][col]
你会写而不是newImage[row * width + col]
。这将避免双重内存引用并受益于 cache locality,因为您正在逐行迭代。
推荐阅读
- javascript - 如何将数据从 PHP 提取到 Javascript?
- python - 一行中多次出现 - 仅查找第一个匹配项
- python - filter even and odd values from a dictionary and add these even and odd values to lists.in python
- c++ - 当第一个操作数不是类对象(成员函数运算符重载)时,为什么编译器不执行隐式转换?
- arrays - 计算c中静态数组的移动平均值
- json - 识别 json 中的项目并更新其中的键和值
- swift - SwiftUI 用图像包装 HStack
- c++ - 为什么我在 C++ 中的输出文件后得到一个“%”?
- android - OneSignal:获取 FCM 令牌的未知错误
- javascript - 在底部插入 Adsense 广告作为粘性广告