我有一个非常简单的代码
val things: Seq[Long] = (1L to 100000000L)
val start: Long = System.nanoTime()
val result = things.sum
val end: Long = System.nanoTime()
println(end-start)
Run Code Online (Sandbox Code Playgroud)
它打印出1790900大约 2ms 之类的东西。
然而,当我介绍我的案例类时
case class Thing(foo: Long) extends AnyVal
Run Code Online (Sandbox Code Playgroud)
这似乎改变了一切。你不相信我?只是看。我会将我的 long 序列映射到Things 并返回到 long 序列:
val things: Seq[Long] = (1L to 100000000L).map(i => Thing(i)).map(t => t.foo)
val start: Long = System.nanoTime()
val result = things.sum
val end: Long = System.nanoTime()
println(end-start)
Run Code Online (Sandbox Code Playgroud)
现在基准的顺序是1058361600。
这怎么可能?
什么时候
首先,在第一次运行时您不会获得合理的计时信息,您需要运行几次以便 JIT 编译器优化代码。
但这里的问题是它Range是惰性的,(1L to 100000000L)只是记录了开始和结束值,它没有分配一个包含 100000000 个元素的向量。所以当你调用 的时候sum,Range只是依次传递每个数字相加直接计算值**。
第二个版本确实创建了一个巨大的Long值列表,然后将它们相加,这将会非常非常慢。
** 感谢 Jörg Mittag 的提示,该提示Range具有sum.
| 归档时间: |
|
| 查看次数: |
55 次 |
| 最近记录: |