真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么理解Scala循環(huán)性能問題

這篇文章主要講解了“怎么理解Scala循環(huán)性能問題”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么理解Scala循環(huán)性能問題”吧!

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),沂南企業(yè)網(wǎng)站建設(shè),沂南品牌網(wǎng)站建設(shè),網(wǎng)站定制,沂南網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,沂南網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

最近我在學(xué)習(xí)我們產(chǎn)品的代碼,看到了類似以下的一段代碼:

x.set(1)  x.set(2)  x.set(3) x.set(4) x.set(5)

我當(dāng)時很是疑惑,為什么不用循環(huán)呢?于是就報了一個Issue,心想這樣寫可能有它的道理,但是需要澄清一下。

另一個問題,就是我發(fā)現(xiàn)代碼里對循環(huán)的使用,各有不同的方式,有人寫array.foreach(f=>_),有人用使用index的for  loop,個人覺得使用foreach的代碼比較簡潔,于是我也報了Issue,看看是不是應(yīng)該使用簡潔的方式來寫循環(huán)。舉例:

for loop

var index = 0 var arr = Array[String] var length = arr.length  for ( index <- 0 to length ) {     do() }

for each

var index = 0 var arr = Array[String] var length = arr.length  for ( index <- 0 to length ) {     do() }

明顯foreach的版本要省不少代碼。

后來和我們的工程師溝通了一下,原來我們是為了性能優(yōu)化了代碼,因為for loop比foreach的性能好,所以我們采用稍微繁瑣的for  loop。至于某些代碼中的foreach是因為遺留的還沒有來得及改動。

Scala的循環(huán)就行性能如何呢?我還是測試一下再說吧。

先看看不同的循環(huán)用法,我這里測試了四種,分別是 while loop,for loop,使用range的foreach,  和使用函數(shù)的foreach。

測試代碼如下:

package profiling  object Loop {    def whileLoop(arr:Array[Int]): Unit = {     var idx = 0     var n = arr.length     val tStart = System.currentTimeMillis()     while (idx < n) {       arr(idx) = 1       idx += 1     }     val tEnd = System.currentTimeMillis()     println("while loop took " + (tEnd - tStart) + "ms")   }    def forLoop(arr:Array[Int]): Unit = {     var idx = 0     var n = arr.length     val tStart = System.currentTimeMillis()     for(idx <- 0 until n) {       arr(idx) = 1     }     val tEnd = System.currentTimeMillis()     println("for loop took " + (tEnd - tStart) + "ms")   }    def foreachLoop(arr:Array[Int]): Unit = {     var n = arr.length     val tStart = System.currentTimeMillis()     (0 until n).foreach{idx => arr(idx) = 1}     val tEnd = System.currentTimeMillis()     println("foreach range took " + (tEnd - tStart) + "ms")   }    def foreachFuncLoop(arr:Array[Int]): Unit = {     val tStart = System.currentTimeMillis()     arr.foreach{ idx => arr(idx) = 1}     val tEnd = System.currentTimeMillis()     println("foreach function took " + (tEnd - tStart) + "ms")   }    def profileRun(n: Int) {     val arr = new Array[Int](n)      whileLoop(arr)     foreachLoop(arr)     forLoop(arr)     foreachFuncLoop(arr)   }    def main(args:Array[String]) {     profileRun(args(0).toInt)   } }

我的環(huán)境是scala 2.13.1 , 調(diào)用500000000次的結(jié)果是:

Bash 代碼

while loop took 344ms foreach range took 484ms for loop took 422ms foreach function took 719ms

可以看出,while loop是最快的,一般形式的foreach最慢,差不多是while  loop的一倍。但是如果使用range的話,foreach循環(huán)也不算太慢。

那么為什么foreach會慢呢?  主要是foreach的函數(shù)調(diào)用帶來了額外的開銷。我們上面看到的數(shù)據(jù)其實是編譯器已經(jīng)優(yōu)化后的數(shù)字,如果我們把java的hotspot編譯選項關(guān)閉,(-Xint)再看看性能。

while loop took 8548ms foreach range took 39392ms for loop took 40799ms foreach function took 103489ms

如果關(guān)閉JIT,foreach的性能要遠遠差于其他幾個選項。

對于循環(huán)的性能,我們可以得出這樣的結(jié)論:

  • 在正常打開JIT的情況下,foreach的性能大概比其他幾個選項慢一倍,其他幾個選項性能接近

  • 在關(guān)閉JIT優(yōu)化的情況下。foreach的性能要遠低于其他選項 (生產(chǎn)環(huán)境一般不考慮)

那么對于開頭講的不用循環(huán),直接重復(fù)代碼呢?我們也測試了一下:

package profiling  object Loop2Repeat {   def whileLoop(): Unit = {     var idx = 0     var n = 5     var x = 0     while (idx < n) {       x = idx       idx += 1     }   }    def repeatLoop(): Unit = {     var x = 0     x = 1     x = 2     x = 3     x = 4     x = 5   }    def test( f:()=>Unit, num: Int, name: String): Unit = {     val tStart = System.currentTimeMillis()     ( 0 until num).foreach{ _ => f}     val tEnd = System.currentTimeMillis()     println(name + " took " + (tEnd - tStart) + "ms")   }    def main(args:Array[String]) {     test(whileLoop, 50000000, "whileLoop")     test(repeatLoop, 50000000, "repeatLoop")   }  }

經(jīng)過50000000次循環(huán),數(shù)據(jù)如下:

whileLoop took 281ms repeatLoop took 47ms

確實,因為循環(huán)控制的邏輯帶來的額外開銷,比簡單的重復(fù)代碼性能下降了不少。

感謝各位的閱讀,以上就是“怎么理解Scala循環(huán)性能問題”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么理解Scala循環(huán)性能問題這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


文章標(biāo)題:怎么理解Scala循環(huán)性能問題
網(wǎng)頁地址:http://weahome.cn/article/ijdejc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部