我很好奇 Kotlin 的 toList 和 IntArray 之间的速度差异

I'm curious about the speed difference between Kotlin's toList and IntArray

很好奇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 返回?

我想知道。

正如 Tenfour04 指出的那样,像这样的微基准测试受到 JVM warm-up、动态编译和分析、系统和时序抖动、缓存效应以及其他它们没有说明的混杂因素的影响你非常在乎。对少量代码进行基准测试是出了名的困难,所以最好使用一个已经为您完成所有艰苦工作的框架。

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

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

A List<Int>Int 对象的 引用的列表(可能存储为数组),每个对象都包含一个原始整数。

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

虽然数组版本对其内存进行简单的线性扫描(可能受益于内存缓存),但列表版本将访问所有单独的 Int 对象(可能位于heap) 以及扫描其引用数组,可能从内存缓存中获得的好处要少得多。

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