이 Scala 코드를 조금만 변경해도 성능이 크게 달라지는 이유는 무엇입니까?
32 비트 Debian 6.0 (Squeeze) 시스템 (2.5GHz Core 2 CPU), sun-java6 6.24-1에서 실행 중이지만 Wheezy의 Scala 2.8.1 패키지를 사용하고 있습니다.
로 컴파일 된이 코드 scalac -optimise
는 실행하는 데 30 초 이상 걸립니다.
object Performance {
import scala.annotation.tailrec
@tailrec def gcd(x:Int,y:Int):Int = {
if (x == 0)
y
else
gcd(y%x,x)
}
val p = 1009
val q = 3643
val t = (p-1)*(q-1)
val es = (2 until t).filter(gcd(_,t) == 1)
def main(args:Array[String]) {
println(es.length)
}
}
그러나 val es=
한 줄을 아래로 이동하고 범위 내 에서 사소한 변경을 수행하면 main
단 1 초 만에 실행됩니다. 이는 동일한 C ++의 성능을보고 비교할 수있을 것으로 기대했던 것과 훨씬 더 비슷합니다. 흥미롭게도 그 자리를 그대로두고 val es=
자격을 부여하는 lazy
것도 동일한 가속 효과를가집니다.
여기서 무슨 일이 일어나고 있습니까? 함수 범위 밖에서 계산을 수행하는 것이 왜 그렇게 느린가요?
JVM은 메서드 호출을 최적화하는 것과 동일한 수준으로 정적 이니셜 라이저 (이것이 무엇인지)를 최적화하지 않습니다. 안타깝게도 그곳에서 많은 작업을 수행하면 성능이 저하됩니다. 이것은 완벽한 예입니다. 이것은 또한 이전 Application
특성이 문제가있는 것으로 간주 된 이유 중 하나 이며, Scala 2.9 DelayedInit
에는 이니셜 라이저에서 나중에 호출되는 메서드로 항목을 이동하는 데 약간의 컴파일러 도움을받는 특성 이있는 이유도 있습니다.
(편집 : "생성자"를 "초기화 자"로 수정했습니다. 다소 긴 오타!)
최상위 수준 개체 블록 내부의 코드는 개체 클래스의 정적 이니셜 라이저로 변환됩니다. Java에서 동등한 것은 다음과 같습니다.
class Performance{
static{
//expensive calculation
}
public static void main(String[] args){
//use result of expensive calculation
}
}
HotSpot JVM은 정적 이니셜 라이저 중에 발생한 코드에 대해 최적화를 수행하지 않습니다. 이러한 코드는 한 번만 실행된다는 합리적 경험이 있습니다.
'IT story' 카테고리의 다른 글
데이터 과학자의 필수 기술 (0) | 2020.12.25 |
---|---|
MongoDB-여러 $ or 작업 (0) | 2020.12.25 |
max-margin CSS 속성이 필요하지만 존재하지 않습니다. (0) | 2020.12.25 |
모든 최근 SVN 커밋 메시지 목록을 얻는 방법은 무엇입니까? (0) | 2020.12.25 |
HTML을 JSON에 매핑 (0) | 2020.12.25 |