Скорость итерации элементов списка слишком мала, если внутри находится другой цикл - PullRequest
0 голосов
/ 26 июня 2019

У меня есть два списка, один со всеми возможными устройствами, а другой только с несколькими устройствами. Мне нужно пройти окончательный список с этим условием: если полный список == один из элементов в меньшем списке, сделайте этот элемент "активным" слишком истинным, иначе оставьте его ложным.

У меня нет проблем при работе с полным списком> 500 устройств и небольшим списком> 50, но когда у меня, например, 2000 устройств, все начинает работать слишком медленно (в Google Pixel 2XL мне нужно подождать около 6 секунд, чтобы закончить работу ).

Вопрос: как я могу увеличить скорость цикла?

Что я сделал до сих пор:

devicesList.forEach { device ->

            device.selected = false

            items.forEach { it ->
                if(it.id == device.id){
                    device.selected = true
                }
            }

Но это слишком медленно для больших данных

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Вы можете немного ускорить его, не используя forEach, который использует интегратор и вместо этого использует цикл for. Вы также можете сломать, когда найдете id, предполагая, что они уникальны

for (i in 0 until devicesList.size) {
    val device = devicesList[i]
    for (j in 0 until items.size) {
         val item = items[j]
         if (item.id == device.id) {
             device.selected = true
             break
         }
     }
}

Предполагая, что ваши id уникальны, вы также можете сделать дубликат списка items и отбросить те, которые были найдены, так что каждый цикл короче, как этот

val copy = items.toMutableList()
for (i in 0 until devicesList.size) {
    val device = devicesList[i]
    for (j in 0 until copy.size) {
        val item = copy[j]
        if (item.id == device.id) {
            device.selected = true
            copy.remove(item)
            break
        }
    }
}

Вы могли бы также подумать о создании карты, где key - это ваш id, чтобы вам не пришлось зацикливаться, и вместо этого вы извлекали элемент напрямую с помощью id. Вы должны взвесить стоимость создания карты в первую очередь.

val map = items.associateBy { it.id }
for (i in 0 until devicesList.size) {
    val device = devicesList[i]
    device.selected = map[device.id] != null
}

Кроме того, вам также следует переместить логику в фоновый поток и дождаться ее завершения.

0 голосов
/ 26 июня 2019

Если все, что вам нужно, это сделать selected = true, если в списке items устройства есть id, вы можете получить все идентификаторы items, например:

val ids = items.map { it.id }

, а затем цикл devices:

devicesList.forEach { it.selected = it.id in ids }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...