我正在写一个用Kotlin写的游戏,并且正在研究如何提高GC的效率。搅拌的主要来源之一是主游戏/渲染循环中调用的for-循环,这会导致迭代器的分配。
关于文件,我发现这一段:
数组上的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])
}
}根据上面的引号,这不应该导致分配任何对象,而是被编译成一个很好的以前Java-5风格的for-循环。然而,我得到的是:
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对象来备份这个循环中的边界检查。这是一个“没有额外创建的对象”的“最佳实现”,还是我遗漏了什么?
更新:所以,在多玩了一会儿并查看了答案之后,对于Kotlin 1.0.2,下面的内容似乎是正确的:
数组:
for (i in array.indices):范围分配for (i in 0..array.size):没有分配for (el in array):没有分配array.forEach:没有分配Collections:
for (i in coll.indices)范围分配for (i in 0..coll.size):没有分配for (el in coll):迭代器分配coll.forEach:迭代器分配发布于 2016-06-03 08:24:53
据我所知,定义for循环的唯一没有分配的方法是
for (i in 0..count - 1)所有其他形式都会导致Range分配或Iterator分配。不幸的是,您甚至不能定义一个有效的反向for循环。
发布于 2016-06-03 16:19:39
若要在不分配额外对象的情况下迭代数组,可以使用下列方法之一。
for-loop for (e in arr) {
println(e)
}forEach扩展 arr.forEach {
println(it)
}forEachIndexed扩展,如果您需要知道每个元素的索引 arr.forEachIndexed { index, e ->
println("$e at $index")
}发布于 2020-02-09 07:45:17
下面是一个准备列表并使用索引和值进行迭代的示例。
val list = arrayListOf("1", "11", "111")
for ((index, value) in list.withIndex()) {
println("$index: $value")
}输出:
0:1
1:11
2:111
另外,下面的代码也是类似的,
val simplearray = arrayOf(1, 2, 3, 4, 5)
for ((index, value) in simplearray.withIndex()) {
println("$index: $value")
}https://stackoverflow.com/questions/37609071
复制相似问题