【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