2014-01-27 2 views
4

필자는지도와 평면 맵을 사용하여 모나드 유형과 통합하는 방법과 이해를 위해 스칼라의 힘을 좋아합니다. 그러나, 나는 또한 중요한 속도 위반없이 단순한 정수 루프를하고 싶다. 스칼라가 비슷한 런타임 성능으로 실행되거나 유사한 바이트 코드로 컴파일되는 논리적으로 동일한 루프 두 개가없는 이유는 무엇입니까?왜 스칼라 for 루프는 논리적으로 동일한 while 루프보다 느립니다?

// This is slow... 
for (i <- 0 until n) println(s"for loop with $i") 

// This runs much faster. It runs roughly at the same speed as Java code doing an identical while or for loop. 
var i = 0; 
while (i < n) { 
    println(s"while loop with $i") 
    i += 1 
} 
+0

물건 속도를 scalaxy/loops를 사용할 수있는'-optimize', 당신은하지 않습니다? –

+0

@KevinWright :'-optimize' 옵션이 실제로하는 일에 대한 설명을 찾는 데 어려움을 겪고 있습니다. 효과에 대한 설명에 대한 포인터가 있습니까? –

+0

@RandallSchulz 버전마다 다르지만 가능성에 대한 좋은 아이디어를 얻으실 수 있습니다. http://magarciaepfl.github.io/scala/ –

답변

4

왜 주된 이유는 무엇입니까? 코드에서

:

for (i <- 0 until n) println(s"for loop with $i") 

당신은 이해 for (i <- 0 until n)에 익명 함수 println(s"for loop with $i")를 전달하고 있습니다. 이는 등가이다 : 그 기능 i 원시적 int 될 수 없다는 것을 의미하는 바이트에서 소거

(0 until n) foreach (i => 
    println(s"for loop with $i") 
} 

, 그 대신 Integer으로 박스형되어야한다. Java는 Fixnum 참조가 없으므로이 비용을 피할 수 있습니다. 스몰 토크는 어떤 오래된 스몰 토크가 얼마나 많은지 감안할 때 특히 실망 스럽습니다.

-optimize을 사용하면 스탁의 트렁크 빌드에서 특히 도움이 될 수 있습니다.

또한 그냥 ... 당신은 * *로 컴파일 확인 :

+0

일부 라이브러리에는 문제가 있으므로 -optimize 옵션을주의하십시오. 나는 Akka가 그들 중 하나라고 믿습니다. –

+0

이것은 유익한 내용이지만 여전히 변명의 여지가 있습니다. 스칼라 컴파일러는이를 명확하게 수정할 수 있습니다. 정수로 복싱 ints 컴파일러 구현을위한 쉽고 깨끗한 수 있지만 이유는 바이트 코드 unboxed 자바 원시 ints 사용할 수 없습니다. – user2684301

+1

@ user2684301 그것은 현재 안정적인 컴파일러가하지 않는 프로젝트 간 최적화 일 것입니다. 'Range.foreach'는 * Generic * 함수를 필요로하므로 표준 라이브러리에서 사용 코드로 복사 한 후 특수화 된 - foreach의 구현이 필요합니다 - 이진 호환성을위한 모든 종류의 재미를 유발합니다. –

관련 문제