【2019-12-07】 Scala for循环嵌套问题

2019-12-07  本文已影响0人  6g3y

先说结论:
for循环嵌套可能导致内存和GC压力变大,我只想说,辣鸡scala 取消 for(;;){}写法
循环的 range 不是栈内变量,如果嵌套循环会new 很多变量在堆里面,导致gc压力变大
建议最内层的小循环可以外提就外提( 1 to 3或者1 to 5这种短程的)

环境:ORACLE JDK1.8,WIN10 ,默认jvm参数

1 to 1000
相当于
1.to(1000)

def to(end: Int): Range.Inclusive = Range.inclusive(self, end)
def inclusive(start: Int, end: Int): Range.Inclusive = new Range.Inclusive(start, end, 1)
因为是调用后返回的变量,所以会发生逃逸,new很多变量
对于本文的这种情况会疯狂new 对象在堆里面

下面是GC测试,对于两种写法,每个大概跑了20多秒
可以发现第一种写法对于新生区的gc还是有一定压力的,0.5秒左右
其次是内存消耗,对于第一种内存直接飞奔到600MB,然后平均在100MB左右
相比之下第二种的内存稳定在40MB

不过我觉得大部分人写代码还是怎么来怎么爽,个人感觉保持这种优化习惯会好一点

Scala for循环
具体代码和GC时间如下:

object  a{
  def main(args:Array[String]) {
    var tick = 0
    for(i<- 1 to 1000000){
      for(j<- 1 to 1000000){
        for(k<- 1 to 1000000){
          for(k<- 1 to 3) {
            tick+=1
          }
        }
      }
    }
  }
} 
image.png

优化后
object  a{
  def main(args:Array[String]) {
    var tick = 0
    val inclusive = 1 to 3
    for(i<- 1 to 1000000){
      for(j<- 1 to 1000000){
        for(k<- 1 to 1000000){
          for(k<- inclusive) {
            tick+=1
          }
        }
      }
    }
  }
} 
image.png
上一篇 下一篇

猜你喜欢

热点阅读