2011-11-18 25 views
1

我在scala中嘗試了一些東西,發現下面的代碼演示了奇怪的性能問題。這裏內聯一個函數調用使計算需要4倍的時間(4秒vs 16秒)。Scala怪異的性能問題

package mypackage 

object MyObject extends Application { 
    class Complex(val real: Double, val imaginary: Double) { 
    def +(operand: Complex): Complex = { 
     new Complex(real + operand.real, imaginary + operand.imaginary) 
    } 
    def *(operand: Complex): Complex = { 
     new Complex(real * operand.real - imaginary * operand.imaginary, 
     real * operand.imaginary + imaginary * operand.real) 
    } 
    def mag2 = real * real + imaginary * imaginary 
    } 

    val iSize = 1250 
    val jSize = 1250 
    val xMin = -2.5 
    val xMax = +1.5 
    val yMin = -2.0 
    val yMax = +2.0 
    val dx = (xMax - xMin)/iSize 
    val dy = (yMax - yMin)/jSize 
    val steps = 50 

    def iterate(c: Complex) = { 
    var z = c 
    var n = 0 
    do { 
     z = z * z + c 
     n += 1 
    } while (n < steps && z.mag2 < 4.0) 
    } 

    // Mandelbrot set using iteration in a function. 
    var startTime = System.currentTimeMillis() 
    for (i <- 0 until iSize; j <- 0 until jSize) { 
    val c = new Complex(xMin + i * dx, yMin + j * dy) 
    iterate(c) 
    } 
    System.out.println("Elapsed time: " + (System.currentTimeMillis() - startTime)/1000.0 + " (s)") 

    // Mandelbrot set using iteration. 
    startTime = System.currentTimeMillis() 
    for (i <- 0 until iSize; j <- 0 until jSize) { 
    val c = new Complex(xMin + i * dx, yMin + j * dy) 
    var z = c 
    var n = 0 
    do { 
     z = z * z + c 
     n += 1 
    } while (n < steps && z.mag2 < 4.0) 
    } 
    System.out.println("Elapsed time: " + (System.currentTimeMillis() - startTime)/1000.0 + " (s)") 
} 

任何想法爲什麼會發生這種情況? Interstingly在「迭代」函數之前添加「@inline」使其花費12 s vs 4 s。

+0

你的scala和java版本是什麼? –

回答

1

請將應用程序替換爲應用程序,並獲得100倍加速。

+1

scala.Application trait已被棄用,因爲它有一些問題(http://www.scala-blogs.org/2008/07/application-trait-considered-harmful.html),如果使用App不適合您,請嘗試在JVM的客戶端模式下運行(不帶-server,或者明確設置-client) –

+0

您已經提出了兩種改進此程序性能的方法 - 將'Application'改爲'App'並在'-client'中運行模式而不是'-server'使其在半秒內運行。但你能解釋它爲什麼會發生? –

+2

「HotSpot沒有優化類初始化器,因爲它們在類的生命中只運行一次,這似乎是一種浪費(除非在這種情況下)......所以......最好的做法是顯式main()方法而不是使用Application。「 (來自http://thread.gmane.org/gmane.comp.lang.scala/12795) –