2013-09-23 47 views
3

這裏的代碼片段,在第一印象,看上去就像是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)成任何形式的字節碼生成javacfor (int i = L; i < H; i += 1)?可能是因爲Scala選擇保持簡單的東西,並希望開發人員只需訴諸性能更高的表單,如while循環時,需要原始循環速度?如果是,爲什麼這麼好,考慮到循環的簡單頻率?

+0

因爲不那麼容易。編譯器必須知道在你傳入的對象上'foreach'的實現是怎麼樣的。這種優化有很多事情可能會出錯。 – drexin

+0

當然,但它可能會特殊情況下'到/直到'至少不是在編譯時靜態可用的這些信息具有足夠的可靠性? –

+1

查看[Spire](https://github.com/non/spire)的'cfor'和['cforRange'](https://github.com/non/spire/commit/6dc6559e7e0814f54745a7427fd5fe216076af10),它們提供正是通過宏來進行這種優化。 –

回答

3

Scala中的理解性能表現現在是一個長期的爭論。

請訪問以下鏈接:

TL,DR:斯卡拉團隊決定專注於更廣泛的優化,比那些不得不贊成一些特定的類和邊界情況(在這種情況下:Range)。

+0

那麼更普遍的優化會不會一般地處理'Range'的情況呢?即使在理論上? –

+0

@ErikAllik:['@ inline' annotation](http://www.scala-lang.org/api/current/#scala.inline)on ['foreach' method](https://github.com/scala) /scala/blob/v2.10.2/src/library/scala/collection/immutable/Range.scala#L135)。 – senia

相關問題