我正在研究用Kotlin编写的游戏,并正在研究改进GC流失.流失的主要来源之一是在主游戏/渲染循环中调用的for循环,导致迭代器的分配.
谈到文档,我发现了这一段:
数组上的for循环被编译为基于索引的循环,该循环不会创建迭代器对象.
如果要迭代数组或带索引的列表,可以这样做:
for (i in array.indices)
print(array[i])
Run Code Online (Sandbox Code Playgroud)
请注意,这种"通过范围的迭代"被编译为最佳实现,而不创建额外的对象.
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])
}
}
Run Code Online (Sandbox Code Playgroud)
根据上面的引用,这不应该导致分配任何对象,而是编译成一个很好的旧的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
Run Code Online (Sandbox Code Playgroud)
这看起来好像调用了一个调用的方法,该方法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:迭代器分配Ily*_*lya 33
要在不分配额外对象的情况下迭代数组,可以使用以下方法之一.
for-环 for (e in arr) {
println(e)
}
Run Code Online (Sandbox Code Playgroud)
forEach 延期 arr.forEach {
println(it)
}
Run Code Online (Sandbox Code Playgroud)
forEachIndexed 扩展,如果你需要知道每个元素的索引 arr.forEachIndexed { index, e ->
println("$e at $index")
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ael 16
据我所知,定义for循环的唯一无分配方法是
for (i in 0..count - 1)
Run Code Online (Sandbox Code Playgroud)
所有其他形式都会导致Range分配或Iterator分配.不幸的是,你甚至无法定义有效的反向for循环.
| 归档时间: |
|
| 查看次数: |
26827 次 |
| 最近记录: |