C# 컴파일러 또는 JIT는 어떤 수준에서 애플리케이션 코드를 최적화합니까?
-
19-08-2019 - |
문제
컴파일러나 JIT에서 수행할 작업을 최적화하는 데 시간을 낭비하지 않도록 코드 크기를 줄이기 위해 이 정보를 알고 싶습니다.
예를 들어:
컴파일러가 속성의 get 함수에 대한 호출을 인라인으로 가정하면 함수 호출을 피하기 위해 반환 값을 로컬 변수에 저장할 필요가 없습니다.
무슨 일이 일어나고 있는지 설명하는 좋은 참고 자료를 추천하고 싶습니다.
해결책
이 기사를보고 싶을 수도 있습니다.
JIT 최적화 - (Sasha Goldshtein -Codeproject)
JIT 최적화 : Inlining I (David Notario)
JIT 최적화 : Inlining II (David Notario)
솔직히 말해서이 수준의 마이크로 디테일에 대해 너무 걱정해서는 안됩니다. 컴파일러/jit'er가 이것에 대해 걱정하게하십시오. 거의 모든 경우보다 더 낫습니다. 매달리지 마십시오 조기 최적화. 코드 작동에 중점을두고 나중에 (a) 충분히 빠르게 실행되지 않는지 나중에 최적화에 대해 걱정하십시오. (b) '크기'문제가 있습니다.
다른 팁
성능이 걱정된다면 프로파일러를 실행하세요. 그 다음에 코드를 변경하세요.백만년이 지나도 시간이 어디로 흘러가는지 100% 정확하게 추측할 수 없을 가능성이 높습니다.0.02% 타이밍을 변경하고 부담의 62%를 기여하는 방법을 그대로 둘 수 있습니다.상황을 더욱 악화시킬 수도 있습니다.프로파일러와 증거가 없으면 당신은 장님입니다.
당신은 할 수 없습니다 추정하다 JIT는 속성 getter를 인라인합니다.그렇게 할 수도 있고 그렇지 않을 수도 있는 데에는 여러 가지 이유가 있습니다.메소드 본문의 크기, 가상, 값 대 참조 유형, 아키텍처, 연결된 디버거 등
"호이스팅"은 여전히 자리를 잡고 여전히 비용 절감을 달성할 수 있습니다. 만약에 코드는 긴밀한 루프에서 반복적으로 호출됩니다.예를 들어:
var count = list.Count;
for(int i = 0 ; i < count ; i++) {...}
(잊어버려 for
대 foreach
위의 토론 - 이것은 직교 토론입니다).위의 경우 "호이스트"가 성능에 도움이 됩니다.하지만 그냥 정말 혼란스럽습니다. 배열의 경우 그 반대이며 다음과 같이 하는 것이 더 효율적입니다. ~ 아니다 그것을 들어 올리십시오:
for(int i = 0 ; i < arr.Length ; i++) {...}
JIT는 이를 인식하고 경계 검사를 제거합니다(배열은 크기가 고정되어 있으므로).
이것은 당신이 보지 말아야 할 일종의 마이크로 최적화처럼 보입니다. 내가 착각하지 않으면 그것은 CLR의 아키텍처와 버전에 따라 어떤 종류의 최적화가 적용되는지에 달려 있습니다.
당신의 방법이 그렇게 많이 부르면 진짜 인라인으로, 스파게티 코드 비용으로 직접 인라인 할 수 있습니다.
알고리즘을 분석하는 것이 좋습니다. 메소드가 속도를 크게 절약하지는 않지만 더 나은 알고리즘은 달리기 시간을 몇 시간으로 몇 시간으로 줄일 수 있습니다.
JIT가 수행하는 가장 강력한 최적화는 일반적으로 인라인입니다. JIT는 수백 가지의 기능을 깊게 인라인 할 수 있습니다 (JikesRVM 의이 그림을 들었습니다). 그들은 항상 인라인으로 불가능하지 않은 것들을 인라인으로 만들어야하며, 필요하다면 나중에 (동적 탈수 최적화라고 함) 나중에 뒷받침 할 것입니다.
귀하의 구체적인 질문에 대해서는 문제의 기능 호출이 더운.