Несколько асинхронных сопрограмм для сокращения времени выполнения в Kotlin

У меня был список, и я хочу выполнить 1 тяжелую задачу со всеми элементами с минимальным временем выполнения. Мое решение - создать ряд сопрограмм, которые равны элементам в списке с диспетчером по умолчанию.

Пример:

list.map {
   async {
      // do heavy task
   }
}.awaitAll()

Предположим, что у меня есть карта с 500 элементами, и на моем устройстве есть максимум 4 потока, которые могут параллельно выполнять максимум 4 тяжелых задачи. Насколько я понимаю, 4 потока будут выполнять 4 задачи параллельно, когда один поток будет выполнен, одна задача будет выделена этому потоку и запущена. Другое решение — создать 4 сопрограммы для 4 потоков и последовательно выполнить 125 задач на поток. Каждый поток запускается последовательно, поэтому он ограничивает несколько раз, чтобы распределить задачу по потокам. Поэтому это быстрее, чем мое решение. Это правильно? Если нет, то какое лучшее решение?


person Quyết Vũ    schedule 07.01.2021    source источник
comment
Мне кажется, что это будет почти то же самое, с первым методом, имеющим более чистый код за крошечные затраты на создание функциональных объектов для каждого элемента.   -  person Tenfour04    schedule 07.01.2021
comment
Да, задача будет выполняться последовательно после того, как 4 задачи не будут завершены. Однако вы можете использовать Dispatchers.IO для максимум 64 потоков, поэтому задача может быть лучше запланирована ОС для получения максимальной выгоды.   -  person Animesh Sahu    schedule 07.01.2021
comment
@AnimeshSahu Да, я знаю это. Я просто говорю о производительности, по моему предположению, второе решение кажется более быстрым, потому что всего в 4 раза оно распределяет задачу по 4 потокам. Между тем, 1-я система решений будет выделять задачу всякий раз, когда поток завершает задачу.   -  person Quyết Vũ    schedule 08.01.2021


Ответы (1)


Я использую следующий код.

Это для списка множества элементов, которые мне нужно преобразовать в другой класс объектов.

/**
     * Method that converts the [FullStopsInfo] list into [Station] list.
     */
    private fun fastConvert(data: MutableList<FullStopsInfo>): Vector<Station> {
        var data1 = data
        val stations = Vector<Station>()

        var offset = 0
        val range = data1.size / Utils.availableCores()// your 4 cores

        val queue = mutableListOf<Deferred<Int>?>()

        val timeProccessing = measureTimeMillis {
            while (data1.isNotEmpty()) {
                val newRange = min(if(range == 0) 1 else range, data1.size)
                val tempTransfers = data1.subList(0, newRange)

                val preferredTask = addToList(tempTransfers, stations)//the transformation goes here
                queue.add(preferredTask)
                preferredTask.start()

                // Move to the next range
                data1 = data1.subList(newRange, data1.size)
                offset += newRange
            }

            runBlocking {
                queue.forEach {
                    it?.await()//wait until all procceses ended
                }
            }
        }

        Log.d(TAG, "End findSearchAllFullDataStation with $timeProccessing")
        return stations
    }
person Capps99    schedule 07.01.2021