Я работаю над игрой, написанной в Котлине, и изучал улучшение оттока GC. Один из основных источников оттока - это петли, называемые в основных циклах игры/рендеринга, которые приводят к распределению итераторов.
Переходя к документации, я нашел этот абзац:
А для цикла по массиву компилируется в цикл, основанный на индексе, который не создает объект итератора.
Если вы хотите итерации по массиву или списку с индексом, вы можете сделать это следующим образом:
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
, который выделяет временный объект IntRange
для резервного копирования границ в этом цикле. Как это "оптимальная реализация" с "никакими добавленными объектами", или я чего-то не хватает?
UPDATE: Итак, после многого другого и поиска ответов, для 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
: распределение итератора