Я заметил удивительную разницу между производительностью Itarable.sum()
и прямой для цикла с ручной суммой. Учтите это:
import kotlin.system.measureTimeMillis
fun main(args: Array<String>) {
var sink = 0;
repeat(5) {
println(measureTimeMillis {
var sum = 0
for (i in 1..10_000_000) {
sum += i
}
sink += sum
})
}
repeat(5) {
println(measureTimeMillis {
sink += (1..10_000_000).sum()
})
}
}
Удивительно, но использование Iterable.sum()
работает в 10 раз медленнее,
по сравнению с кодом, который почти идентичен реализации sum () .
Почему это так?
Обновление:
Когда я нацеливаюсь на js, тогда sum () лишь немного медленнее.
measureTimeMillis()
можно определить как:
import kotlin.js.Date
public inline fun measureTimeMillis(block: () -> Unit): Double {
val start = Date.now()
block()
return Date.now() - start
}
Update2:
На той же машине Linux, jvm sum () даже медленнее, чем js. Вот результаты для 100_000_000 итераций для jvm (Oracle jdk9) и js (последний chrome):
105 // jvm raw loop
76 // jvm raw loop (jit?)
75 // jvm raw loop (jit?)
75 // jvm raw loop (jit?)
70 // jvm raw loop (jit?)
633 // jvm sum()
431 // jvm sum()
562 // jvm sum()
327 // jvm sum() (jit?)
332 // jvm sum() (jit?)
110 // js raw loop
108 // js raw loop
232 // js raw loop
227 // js raw loop
227 // js raw loop
321 // js sum()
284 // js sum()
264 // js sum()
266 // js sum()
265 // js sum()
Итак, на той же машине jvm работает медленнее, чем js при использовании sum()
. Еще один сюрприз.