2012-05-25 2 views
2

클라이언트가 출력을 디버깅하는 데 도움이되도록 자주 정보를 출력해야하는 코드가 있습니다. 이는 매우 수학적입니다.컴파일러 상수, 최적화 및 성능

성능상의 이유로 프로덕션에서 추적 기능을 사용하지 않으려 고하지만, 자주 주석 처리를해야하는 번거 로움이 있습니다.

I ...

using System.Diagnostics; 

const bool TRACING_ENABLED = false; 

//math math math.... 

Trace.WriteLineIf(TRACING_ENABLED, "Minimum Nitrogen Yield: " + minYieldNitrogen); 
Trace.WriteLineIf(TRACING_ENABLED, "Minimum Water Yield: " + minYieldWater); 
Trace.WriteLineIf(TRACING_ENABLED, "Minimum Seed Yield: " + minYieldSeed); 

//more math math trace math trace math... 

내 질문은 ... 바로 설정 같은 코드했습니다이 활성화 및 디버깅에 대한 추적을 불가능하게하는 가장 좋은 방법입니다? 이러한 종류의 줄이 코드 전체에 흩어져 있기 때문에 if 또는 그 주변에 무엇이든지 정리해서 정리할 필요가 없기를 바랬습니다.

컴파일 타임에 빌드 할 때 false 상수가 제공되므로 컴파일러에서이 라인을 어셈블리 밖으로 최적화 할 예정입니까?

통찰력을 가져 주셔서 감사합니다.

답변

3

대신 ConditionalAttribute 및 컴파일러 플래그를 사용하여이 문제를 처리 할 것입니다.

이것은 의 장점을 가지고 생산 코드에서 메서드를 완전히 제거하므로 조건부 검사가 수행되지 않습니다. 이렇게

, 당신은 같은 당신의 자신의 방법을 만들 수 :

[Conditional("TRACE")] 
public WriteTraceLine(string message) 
{ 
    Trace.WriteLine(message); 
} 

그리고 디버그/비 프로덕션 빌드 설정에서 TRACE 플래그를 가지고있다. 이 메소드는 해당 플래그가 정의 될 때 컴파일 된 소스 (호출 포함)에만 존재하게됩니다.

+0

'[조건부 ("TRACE = 1")]'과 같은 명확한 조건을 사용할 수 있습니까? – jocull

+0

내 실수는 실제로 ... 나는 아직 컴파일러 기호에 숙제를하지 않았다 - 그들은 이런 식으로 작동하지 않습니다. – jocull

+0

@jocull 네, 그냥 ConditionalAttribute 플래그를 사용할 수 있습니다. 플래그는 또한 대소 문자를 구별합니다 *, 사람들을 가끔씩 이동시킵니다 ... –

2

Debug.WriteLine() 메서드도 살펴 보겠습니다. 모든 디버그 메서드는 Reed의 Conditional 특성을 사용하지만 대신 "디버그"상수의 정의를 기반으로합니다 (기본 디버그 빌드 구성에서는 무료로 제공되고 기본 릴리스 빌드 구성에서는 없음). Debug 메서드는 Trace와 동일한 Listener 컬렉션을 사용합니다. 아이디어는 당신이 소프트웨어의 모든 빌드에서 기록하거나 보여주고 자하는 것을 위해 Trace.WriteLine()을 사용하고, Debug.WriteLine()을 사용하여 소프트웨어의 디버그 빌드에 기록하거나 보여주고 자하는 추가 텍스트를 사용하는 것이다.

+1

다른 목적을 위해 릴리스 빌드에서 추적을 수행해야하는 경우가 아니라면이 방법이 유용합니다. 자신의 상수로 자신을 굴리면 (또는 상수를 변경하면) 많은 유연성이 추가됩니다. –

+0

릴리스 빌드에서 추적이 필요한 경우 TraceSource (http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource)를 살펴보십시오. –

+0

동의합니다. 2 단계 이상의 출력 (디버그의 모든 시간 및 조건부)이 필요하다면 추적 출력의 추가 레벨을 제어하는 ​​데 사용할 수있는 추가 상수를 정의하는 것이 좋습니다. Verbose와 같은 Trace 및 Debug와 유사한 구조로 전체 정적 클래스를 만들 수 있습니다.이 클래스는 Trace를 장면 뒤에 사용하지만 VERBOSE와 같은 C-T 상수를 조건으로합니다. – KeithS

0

Trace.WriteLineIf(condition, message) 대신 Debug.WriteLine(message)을 사용하십시오.

디버그 빌드에서이 메서드에 대한 호출은 정상적으로 컴파일됩니다. 릴리스 빌드에서 컴파일러는 호출 또는 매개 변수 평가를위한 코드를 내 보내지 않습니다. 귀하의 질문을 정확하게 이해한다면, 귀하가 원하는 것입니다.

정확하게 말하면, Debug.WriteLine(message)에는 [ConditionalAttribute("DEBUG")]이 적용됩니다. 결과적으로 컴파일 중에 DEBUG 기호가 정의 된 경우에만 컴파일러에서 해당 코드를 호출하는 코드가 생성됩니다. 이 기호는 표준 Visual Studio Debug 빌드에서는 정의되지만 Release 빌드에서는 정의되지 않습니다.

자세한 내용은 http://msdn.microsoft.com/en-us/library/9z9k5ydzhttp://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx을 참조하십시오.당신이 할 수있는 어쩌면 무엇을

0

는 자신의 클래스를 작성하는 것입니다

public class MyTrace 
{ 
    [Conditional("TRACE")] 
    public static void Trace(string message) 
    { 
      //trace code goes here 
    } 
    [Conditional("DEBUG")] 
    public static void Debug(string message) 
    { 
      //Debug code goes here 
    } 
} 
이것의 장점은 당신이 조건부 컴파일을 사용하여 구성 논리를 추가하거나

Log4Net 같은 로깅 패키지를 사용할 수 있습니다 것입니다

물론 사용하실 수 있습니다.

.... 
    MyTrace.Trace("....."); 
    MyTrace.Debug("....."); 
    ....