這裏的代碼片段,在第一印象,看上去就像是scalac
可以很容易地優化掉的例子:爲什麼scalac不能優化簡單`for`構造的開銷?
val t0 = System.nanoTime()
for (i <- 0 to 1000000000) {}
val t1 = System.nanoTime()
var i = 0
while (i < 1000000000) i += 1
val t2 = System.nanoTime()
println((t1 - t0).toDouble/(t2 - t1).toDouble)
上面的代碼打印76.30068413477652
和比例似乎得到儘可能的差一些迭代增加。
有什麼特別的原因scalac
選擇不優化for (i <- L to/until H)
成任何形式的字節碼生成javac
爲for (int i = L; i < H; i += 1)
?可能是因爲Scala選擇保持簡單的東西,並希望開發人員只需訴諸性能更高的表單,如while
循環時,需要原始循環速度?如果是,爲什麼這麼好,考慮到循環的簡單頻率?
因爲不那麼容易。編譯器必須知道在你傳入的對象上'foreach'的實現是怎麼樣的。這種優化有很多事情可能會出錯。 – drexin
當然,但它可能會特殊情況下'到/直到'至少不是在編譯時靜態可用的這些信息具有足夠的可靠性? –
查看[Spire](https://github.com/non/spire)的'cfor'和['cforRange'](https://github.com/non/spire/commit/6dc6559e7e0814f54745a7427fd5fe216076af10),它們提供正是通過宏來進行這種優化。 –