kotlin - 无需额外对象分配的数组/列表迭代

我正在开发一个用 Kotlin 编写的游戏,并且正在研究如何改善 GC 流失率。流失的主要来源之一是在主游戏/渲染循环中调用的 for 循环,导致分配迭代器。

翻到文档,我找到了这一段:

A for loop over an array is compiled to an index-based loop that does not create an iterator object.

If you want to iterate through an array or a list with an index, you can do it this way:

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

Note that this “iteration through a range” is compiled down to optimal implementation with no extra objects created.

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-loop。然而,我得到的是这样的:

      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:不分配

收藏:

  • for(coll.indices 中的 i) 范围分配
  • for (i in 0..coll.size): 没有分配
  • for (el in coll):迭代器分配
  • coll.forEach:迭代器分配

最佳答案

要在不分配额外对象的情况下迭代数组,您可以使用以下方法之一。

  1. for-循环
    for (e in arr) {
        println(e)
    }
  1. forEach 扩展
    arr.forEach {
        println(it)
    }
  1. forEachIndexed 扩展,如果你需要知道每个元素的索引
    arr.forEachIndexed { index, e ->
        println("$e at $index")
    }

https://stackoverflow.com/questions/37609071/

相关文章:

file - 在 Kotlin 中递归列出文件

android - 类 'MyFirebaseMessagingService' 不是抽象的,也没有

kotlin - 函数定义: fun vs val

java - Kotlin 获取类型为字符串

kotlin - 'by' 关键字在 Kotlin 中的作用是什么?

kotlin - Kotlin 中的交换函数

java - 为 Kotlin 创建 POJO 类

android - 如何像在 Swift 中一样从 Kotlin 中的函数返回多个值?

input - 在 Kotlin 中读取控制台输入

android - 产品 flavor : Duplicate class found