Котлин: Есть ли способ повторить это как последовательность? - PullRequest
0 голосов
/ 04 мая 2019

Я делаю фильтр изображений, я уже сделал это, но я читал, что для больших коллекций было бы лучше использовать последовательность для итерации, и, поскольку это изображение размером 8 КБ, я полагаю, что получу некоторую производительностьиз-за его ленивой инициализации с Sequence<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
}

1 Ответ

0 голосов
/ 05 мая 2019

Я читал, что для больших коллекций было бы лучше использовать последовательность для итерации

Что вы, вероятно, прочитали, так это то, что при наличии функционального конвейера, подобного myCollection.filter(...).map(...).first(...), производительность можно улучшить, используя Sequence, в основном по двум причинам:

  1. последовательность не будет обрабатывать все элементы, если в этом нет необходимости (first() и конец может привести к ее завершению до просмотра всех элементов)
  2. последовательность не будет создавать промежуточные коллекции для каждого шага конвейера (например, фильтра или карты), в отличие от обычных коллекций

В вашем случае у вас даже нет конвейера функциональных операций, и вы не создаете промежуточные коллекции, поскольку вы создаете и заполняете свой результат напрямую. Более того, вы не можете завершить работу раньше, потому что вы все равно хотите обработать все пиксели, поэтому Sequence может быть уместным, но это не обязательно будет улучшением производительности.

Если вы компилируете этот код Kotlin для JVM, то есть, по крайней мере, одна вещь, которую вы можете сделать для повышения производительности:

Вместо использования 2D-массива используйте 1D-массив со специальным индексированием. Более конкретно, вместо newImage[row][col] вы бы написали newImage[row * width + col]. Это позволит избежать двойных ссылок на память и использовать локальность кэша , поскольку вы выполняете итерацию строка за строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...