Array / List iteration без дополнительных распределений объектов

Я работаю над игрой, написанной в Котлине, и изучал улучшение оттока GC. Один из основных источников оттока – это петли, называемые в основных циклах игры / рендеринга, которые приводят к распределению итераторов.

Переходя к документации, я нашел этот пункт:

Цикл for по массиву скомпилирован в цикл на основе индекса, который не создает объект итератора.

Если вы хотите итерации по массиву или списку с индексом, вы можете сделать это следующим образом:

for (i in array.indices) print(array[i]) 

Обратите внимание, что эта «итерация через диапазон» сводится к оптимальной реализации без создания дополнительных объектов.

https://kotlinlang.org/docs/reference/control-flow.html#for-loops

Это правда? Чтобы проверить, я взял эту простую программу Kotlin и проверил сгенерированный байт-код:

 fun main(args: Array<String>) { val arr = arrayOf(1, 2, 3) for (i in arr.indices) { println(arr[i]) } } 

Согласно приведенной выше цитате, это не должно приводить к каким-либо выделенным объектам, но скомпилировать их до старого старого стиля pre-Java-5 для цикла. Однако я получил следующее:

  41: aload_1 42: checkcast #23 // class "[Ljava/lang/Object;" 45: invokestatic #31 // Method kotlin/collections/ArraysKt.getIndices:([Ljava/lang/Object;)Lkotlin/ranges/IntRange; 48: dup 49: invokevirtual #37 // Method kotlin/ranges/IntRange.getFirst:()I 52: istore_2 53: invokevirtual #40 // Method kotlin/ranges/IntRange.getLast:()I 56: istore_3 57: iload_2 58: iload_3 59: if_icmpgt 93 

Это выглядит так, как будто getIndices метод, называемый getIndices который выделяет временный объект IntRange для проверки границ в этом цикле. Как это «оптимальная реализация» с «никакими добавленными объектами», или я что-то упускаю?

ОБНОВЛЕНИЕ: Итак, после многого другого и поиска ответов, для Kotlin 1.0.2 следующее:

Массивы:

  • for (i in array.indices) : распределение диапазона
  • for (i in 0..array.size) : нет выделения
  • for (el in array) : нет распределения
  • array.forEach : отсутствие распределения

Коллекции:

  • for (i in coll.indices) распределения диапазона
  • for (i in 0..coll.size) : нет распределения
  • for (el in coll) : распределение итератора
  • coll.forEach : распределение итератора

Насколько я знаю, единственным способом определения цикла for является

 for (i in 0..count - 1) 

Все остальные формы приводят либо к распределению Range либо к распределению Iterator . К сожалению, вы даже не можете определить эффективную обратную for цикла.

Для итерации массива без выделения дополнительных объектов вы можете использовать один из следующих способов.

  1. for -loop
  for (e in arr) { println(e) } 
  1. forEach расширения
  arr.forEach { println(it) } 
  1. forEachIndexed , если вам нужно знать индекс каждого элемента
  arr.forEachIndexed { index, e -> println("$e at $index") } 
Intereting Posts
Прогард и Котлин-Отражение / Котлин Аннотации Как представить таблицу соединений с дополнительным полем с помощью eBean и Kotlin? Kotlin: Java Util Date to String для привязки данных Использование сокета для пользовательского протокола через tcp Создание активности для входа в систему Расширить класс данных в Котлине KDoc Аннотации, не отображаемые в Dokka, генерируются HTML переместить вид в зависимости от направления движения Почему не переупорядочивает код в файлах Kotlin в Intellij? Добавить представление в пользовательскую группу просмотра Что не так с использованием инсталляции setter для Android ViewModel против внедрения и ввода ViewModel.Factory? KMango: обновить коллекцию с помощью col.updateOne / col.updateMany Используя начальное значение наблюдаемого в подписке вместе с отображаемым MutableLiveData с многократным укладом Kotlin Generic не работает Android предотвращает просмотр от успешных событий