【问题标题】:I'm curious about the speed difference between Kotlin's toList and IntArray我很好奇 Kotlin 的 toList 和 IntArray 的速度差异
【发布时间】:2021-02-06 22:02:40
【问题描述】:

我很想知道 Kotlin 的 toList 是在什么中返回的,所以我测试了它。

fun loop(i: Int){
    for(i in 0..i){}
}

fun main() {
    val list: List<Int> = (1..100000).toList()
    val arr =  IntArray(100000) { i -> i}

    println("list : ForLoop Time: " + measureNanoTime {
        for (i in list) { loop(i) }
    })

    println("list : ForEach Time: " + measureNanoTime {
        list.forEach { i -> loop(i) }
    })

    println("Array : ForLoop Time: " + measureNanoTime {
        for (i in arr) { loop(i) }
    })

    println("Array : ForEach Time: " + measureNanoTime {
        arr.forEach { i-> loop(i) }
    })
}

输出:

我查了一下,toList是以Array的形式返回的,但是不知道为什么速度相差很大。 toList 是否作为 LinkedList 返回?

我想知道。

【问题讨论】:

  • 对于基准测试,您应该openjdk.java.net/projects/code-tools/jmh
  • 这不是一个有效的基准。您需要一个基准测试库。
  • IntArray 是 JVM 中使用的原始数组,因此应该比 ArrayList 或任何实现要快得多(因为它肯定会保存引用而不是原始值)。

标签: kotlin arraylist tolist


【解决方案1】:

正如 Tenfour04 所指出的,像这样的微基准测试会受到 JVM 预热、动态编译和分析、系统和时序抖动、缓存效果以及其他混淆因素的影响。全部。众所周知,对一小段代码进行基准测试非常困难,因此最好使用一个已经为您完成所有艰苦工作的框架。

但是,您在这里看到的效果之一似乎很可能是拳击。

IntArray 是一个(原始)整数数组。

List&lt;Int&gt; 是对Int 对象的引用 列表(可能存储为数组),每个对象都包含一个原始整数。

所以列表不仅需要存储一个数组,还需要存储所有单独的Int 对象;因此,它会占用更多的内存——可能要多几倍。

虽然数组版本对其内存进行简单的线性扫描(可能受益于内存缓存),但列表版本也将访问所有单独的 Int 对象(可能位于堆中不可预测的位置)就像扫描它的引用数组一样,可能从内存缓存中获得的好处要少得多。

如果您想要更公平的比较,您可能会发现Array&lt;Int&gt; 的行为更像List&lt;Int&gt;。 (当然,推荐使用Array&lt;Int&gt;,这个问题说明了一个很好的理由为什么不这样做!)

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 2012-05-11
    • 2013-07-06
    • 2015-08-07
    • 2019-10-02
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多