[C#] 디버그 대 릴리스 성능

다음 단락을 만났습니다.

“Visual Studio에서 코드를 컴파일 할 때 IDE의 디버그 및 릴리스 설정은 성능과 거의 차이가 없습니다. 생성 된 코드는 거의 같습니다. C # 컴파일러는 실제로 최적화를 수행하지 않습니다. C # 컴파일러는 IL을 뱉어 내고 런타임에 모든 최적화를 수행하는 JITer입니다. JITer에는 디버그 / 릴리스 모드가 있으며 성능에 큰 차이가 있습니다. 하지만 프로젝트의 디버그 또는 릴리스 구성을 실행하든 디버거가 연결되어 있는지를 결정하는 것은 아닙니다.”

소스는 여기에 있고 팟 캐스트는 여기에 있습니다 .

누군가 이것을 실제로 증명할 수있는 Microsoft 기사로 안내 할 수 있습니까?

인터넷 검색 ” C # 디버그와 릴리스 성능 “은 대부분 ” 디버그에 많은 성능 히트가 발생했습니다 “, ” 릴리스가 최적화되었습니다 “및 ” 디버그를 프로덕션에 배포하지 않음 “이라는 결과를 반환합니다 .



답변

부분적으로 사실입니다. 디버그 모드에서 컴파일러는 모든 변수에 대해 디버그 기호를 생성하고 코드를있는 그대로 컴파일합니다. 릴리스 모드에서 일부 최적화가 포함됩니다.

  • 사용하지 않는 변수는 전혀 컴파일되지 않습니다
  • 변하지 않는 것으로 판명 된 경우 일부 루프 변수는 컴파일러에 의해 루프에서 제거됩니다.
  • #debug 지시문에 작성된 코드는 포함되지 않습니다.

나머지는 JIT에 달려 있습니다.

최적화의 전체 목록 에 여기 의 호의 에릭 Lippert의를 .


답변

성능 문제에 대해 “증명”하는 기사는 없습니다. 변경으로 인한 성능 영향에 대한 주장을 증명하는 방법은 현실적으로 제어되는 조건에서 두 가지 방법으로 모두 테스트하고 테스트하는 것입니다.

성능에 대한 질문을하고 있으므로 성능에 대해 분명히 신경을 씁니다. 퍼포먼스에 관심이 있다면, 올바른 목표는 퍼포먼스 목표를 설정하고 그 목표에 대한 진행 상황을 추적하는 테스트 스위트를 작성하는 것입니다. 이러한 테스트 스위트가 있으면 “디버그 빌드가 느리다”와 같은 문장의 진실 또는 허위를 스스로 테스트하기 위해 쉽게 사용할 수 있습니다.

또한 의미있는 결과를 얻을 수 있습니다. “느리게”는 1 마이크로 초 느리거나 20 분 느리게 명확하지 않기 때문에 의미가 없습니다. “현실적인 조건에서 10 % 느리게”가 더 의미가 있습니다.

질문에 대한 답변을 제공하는 장치를 구축하는 데이 질문을 온라인으로 조사하는 데 소요 된 시간을 보내십시오. 그렇게하면 훨씬 정확한 결과를 얻을 수 있습니다. 온라인에서 읽은 내용 발생할 수있는 일 에 대한 추측 일뿐 입니다. 프로그램이 어떻게 작동하는지에 대한 다른 사람들의 추측이 아니라 자신이 수집 한 사실 때문입니다.


답변

성능에 대해서는 언급 할 수 없지만 “제품에 디버그를 배포하지 마십시오”라는 조언은 여전히 ​​큰 제품에서 디버그 코드가 상당히 다른 기능을 수행하기 때문에 여전히 유효합니다. 하나는 디버그 스위치를 활성화하고 다른 하나는 프로덕션 코드에 속하지 않는 여분의 중복성 검사 및 디버그 출력이있을 수 있습니다.


답변

에서 MSDN의 사회

잘 문서화되어 있지 않습니다. 여기 내가 아는 것이 있습니다. 컴파일러는 System.Diagnostics.DebuggableAttribute의 인스턴스를 생성합니다. 디버그 버전에서 IsJitOptimizerEnabled 속성은 True이고 릴리스 버전에서는 False입니다. ildasm.exe를 사용하여 어셈블리 매니페스트에서이 특성을 볼 수 있습니다.

JIT 컴파일러는이 속성을 사용하여 디버깅을 어렵게하는 최적화를 비활성화합니다. 루프 불변의 호이 스팅처럼 코드를 이동시키는 것. 선택된 경우 성능에 큰 차이를 만들 수 있습니다. 그러나 보통은 아닙니다.

중단 점을 실행 주소에 매핑하는 것은 디버거의 작업입니다. JIT 컴파일러가 생성 한 .pdb 파일 및 정보를 사용하여 코드 주소에 대한 IL 명령어 명령을 제공합니다. 자체 디버거를 작성하려면 ICorDebugCode :: GetILToNativeMapping ()을 사용합니다.

JIT 컴파일러 최적화가 사용 불가능하므로 기본적으로 디버그 배치가 느려집니다.


답변

당신이 읽는 것은 매우 유효합니다. 디버그 코드 (#IF DEBUG 또는 [Conditional ( “DEBUG”)]), 최소 디버그 심볼 로딩을 포함하지 않고 JIT 최적화로 인해 릴리스가 일반적으로 더 늦어지고 종종로드 시간을 단축시키는 작은 어셈블리가 고려되지 않습니다. 더 광범위한 PDB 및로드 된 기호로 인해 VS에서 코드를 실행할 때 성능 차이가 더 분명하지만 독립적으로 실행하면 성능 차이가 덜 분명해질 수 있습니다. 특정 코드는 다른 코드보다 더 잘 최적화되며 다른 언어와 마찬가지로 동일한 최적화 휴리스틱을 사용합니다.

Scott은 인라인 분석법 최적화에 대해 잘 설명하고 있습니다.

디버그 및 릴리스 설정에 대해 ASP.NET 환경에서 다른 이유를 간략하게 설명하는 이 문서 를 참조하십시오 .


답변

성능과 디버거가 연결되어 있는지 여부와 관련하여 한 가지 유의해야 할 점은 놀라운 일입니다.

우리는 많은 빡빡한 루프를 포함하는 코드 조각을 가지고 있었고, 디버그하는 데 영원히 걸리는 것처럼 보였지만 자체적으로 잘 실행되었습니다. 다시 말해, 문제가 발생한 고객이나 고객은 없지만 디버깅 할 때 당밀처럼 작동하는 것 같습니다.

범인은 Debug.WriteLine타이트한 루프 중 하나였으며 수천 개의 로그 메시지를 뱉어 내고 디버그 세션에서 잠시 동안 빠져 나갔습니다. 디버거가 연결되어 이러한 출력을 수신하면 프로그램 속도가 느려지는 오버 헤드가있는 것 같습니다. 이 특정 코드의 경우 자체적으로 런타임이 0.2-0.3 초이고 디버거가 연결되었을 때 30 초 이상이었습니다.

그러나 간단한 해결책은 더 이상 필요하지 않은 디버그 메시지를 제거하십시오.


답변

에서 MSDN 사이트 …

릴리스 및 디버그 구성

프로젝트에서 작업하는 동안 일반적으로 디버그 구성을 사용하여 응용 프로그램을 빌드합니다.이 구성을 사용하면 디버거에서 변수 값을보고 실행을 제어 할 수 있기 때문입니다. 릴리스 구성에서 빌드를 작성하고 테스트하여 한 유형의 빌드에서만 나타나는 버그가 발생하지 않았는지 확인할 수 있습니다. .NET Framework 프로그래밍에서 이러한 버그는 매우 드물지만 발생할 수 있습니다.

최종 사용자에게 애플리케이션을 배포 할 준비가되면 릴리스 빌드를 작성하십시오. 릴리스 빌드는 훨씬 작으며 일반적으로 해당 디버그 구성보다 성능이 훨씬 우수합니다. 프로젝트 디자이너의 빌드 창 또는 빌드 도구 모음에서 빌드 구성을 설정할 수 있습니다. 자세한 내용은 빌드 구성을 참조하십시오.