2016-11-19 6 views
0

일부 코드의 성능을 측정 할 것입니다. body 결과를 보존하기 위해 도입테스트에서 불필요한 코드 제거를 막기 위해 volatile var에 결과를 작성하십시오.

def timed[T](body: => T) = { 
    val start = System.currentTimeMillis 
    blackHole = body 
    val end = System.currentTimeMillis 
    end - start 
} 

blackHole 변수 : 목적 , 나는 다음과 같은 방법을 소개했다. 이 작업은 의 JVM에 의한 코드 제거을 방지하기 위해 수행됩니다.

@volatile 
var blackHole: Any = _ 

왜 하나가 변수 volatile를 표시해야합니다 : 어떤 책에서

다음과 같이 blackHole 선언되어야한다는 성명이있다?

+1

> 1 초 이상 실행하지 않는 경우 jmh와 같은 마이크로 벤치 마크 프레임 워크를 사용해야합니다 (http://stackoverflow.com/q/504103/1362755 – the8472

+0

참조). 그리고 이상적으로 당신이 명확하게하고 싶은 진술을 인용하십시오. 또한 귀하의 질문 제목이 당신이 여기서 질문 한 질문과 잘 일치하지 않습니다. – Ivan

+0

@ the8472 예, 알고 있습니다. 그러나 특별한 경우에는 왜 여기에 변동성이 중요한지 이해하려고합니다. 스칼라에서 – Aliaxander

답변

1

코드를 실행하면 중요한 코드 부분에 대해 Just In Time 컴파일러 (JIT)가 호출됩니다. 수행하려고하는 몇 가지 최적화가 있습니다.

데드 코드 제거. 코드에는 관찰 할 수있는 부작용이 없으므로 제거 할 수 있습니다.

결과를 인스턴스 변수에 할당하면 그 값이 '사용되지 않음'임을 증명하기가 더 어려워집니다. 잠재적으로 다른 클래스/스레드의 누군가가 나중에 해당 값을 사용할 수 있습니다.

휘발성 부분은 내 벤치 마크에서 실제로 필요하지 않았습니다. 내가 읽은 블로그 중 하나는 JIT가 변수가 없으면 변수를 쓸 수 없다는 것입니다 (link).

+0

# 2와 관련이 있지만이 특정 유형의 최적화에 대한 정보를 찾을 수 없습니다. 참조를 제공 할 수 있습니까? – Aliaxander

+0

이것은 전체가 루프에서 실행될 때 특히 적용될 수 있습니다. 컴파일러는 루프 실행의 마지막 결과 만 사용하도록 결정할 수 있습니다. 그러면 모든 이전 반복이 DCE의 영향을받습니다. – the8472

+0

@ Aliaxander re : # 2, 그것은 내가 읽은 블로그에있었습니다. 테스트를 위해 작은 벤치 마크를 만들었고 제 경우 ('build 1.8.0_45-b14')에서 휘발성이 필요하지 않았습니다. Dima의 대답은이 시점에서 약간의 장점이있을 수 있습니다. 확인되지 않은 부분을 제외시키기 위해 내 대답을 업데이트하겠습니다. – Ivan

0

이유는 휘발성이 없기 때문에 코드는 할당이없는 것처럼 코드가 죽어 있다는 것입니다. 비 휘발성 변수에 쓸 때 해당 연산의 결과가 해당 변수에 액세스하는 다른 스레드에 의해 보장되지 않을 수 있습니다. 따라서, 같은 스레드에서 결과를 다시 읽지 않는 한, 외부 세계에 관한 한 글은 발생하지 않았습니다.

+0

여기 누군가가 나에 대한 복수를합니까? :) – Dima