2014-11-30 4 views
7

오픈 소스 C++ 응용 프로그램에 기여합니다. 해당 응용 프로그램에서 같은로깅 성능 및 운영자 <<

if (Debug) std::cout << "MyClass | my debug message" << MyExpensiveStringConvertion() << std::endl; 

같은 라인으로 수행하는 모든 로깅 나는 그런 그 자동 형식화하는 작업을 수행 어떤 부스트, easylogginppp, 같은 기존의 프레임 워크 중 하나를 사용하여 제안 (다른 언어로) 고급 로깅 ​​프레임 워크를 사용하는 데 사용되는 런타임에 구성 할 수 있습니다.

하지만 "(디버그)이"거의 오버 헤드가 사용을 writting 동안

Log(debug) << "MyClass | my debug message" << MyExpensiveStringConvertion() 

가 < < 연산자와 MyExpensiveStringConvertion() 이벤트 로깅의 계산 모두가 필요하다는 응답 하였다는 불가능하다. 이 인수가 맞습니까? 맞으면 우리가 신경 써야합니까? 그렇게 대부분의 로깅 프레임 워크가 그렇게 명백하게 대부분의 개발자가 신경 쓰지 않는 것처럼 보입니다.

업데이트 : (디버그) 양식은 간단한 bool 테스트 만 필요하지만 로깅 프레임 워크는 비용 절감을 위해 모든 종류의 트릭을 구현할 것으로 예상했습니다. Dietmar Kühl이 언급 한 "#define LOG (레벨) if (doDebug (level)) 로그 (레벨)".

+3

'MyExpensiveStringConver [s] ion()'이 (는) 더 많은 인스턴트 메신저로 불려지는 것은 맞습니다. '<<'의 평가보다 더 중요하다. – Ryan

+1

대부분의 로깅 프레임 워크는 쓰레기입니다. 그래서 내가 내 자신의 것을 썼다. – doc

+0

@doc 나도, 비록 내가 적절한 프레임 워크가 이미 처리했을 (예 : 누군가가 프로세스를 복제하고 로그 파일에 고아가 된 핸들을 남겨 두었 기 때문에 로그 롤링이 실패했을 수 있음) 생산 환경에서 성가신 문제가 발생하지만 좋은 메시지라고 생각하는 –

답변

0

감사를 표현하는 것은 아닙니다.

(디버그)보다 효율적으로 보이지만, 대부분의 로깅 프레임 워크는 사실 다른 포스터가 ++ easylogging 예를 들어

을하여 mentionnned 트릭을 포함하는 방식으로 구현 될 것으로 보인다 경우 모두 구현 DLOG 및 DCLOG #DEFINE DCLOG (LEVEL, ...)의 경우 (_ELPP_DEBUG_LOG) CLOG (LEVEL, VA_ARGS)

및 GLog가 (구글 로깅) 로서도 또한 어느 전역 변수를 확인하거나 중지 할 수 있습니다 DLOG 컴파일 시간. glog doc는 또한 다음과 같이 말합니다. "" " glog에서 제공하는 조건부 로깅 매크로 (예 : CHECK, LOG_IF, VLOG, ...)는 신중하게 구현되며 조건이 거짓 일 때 오른쪽 표현식을 실행하지 않습니다. 다음 검사는 응용 프로그램의 성능을 희생하지 않을 수 있습니다

CHECK (obj.ok) < < obj.CreatePrettyFormattedStringButVerySlow();. "" "

나는 부스트 로깅이 유사한 성능 트릭

를 구현하는 것 같아요
4

출력 작업 앞에 조건이없는 주요 문제는 모든 인수가 평가되고 있다는 것입니다. 실제 출력 작업을 단락시키는 것은 쉽습니다 (Log(debug)std::ios_base::failbit이 설정된 상태로 스트림을 반환하는지 확인하십시오).하지만 모든 인수를 평가할 때 로깅하는 동안 지출하지 않으려는 오버 헤드가 발생하는 경향이 있습니다. 물론, 당신은

#define LOG(level) if (doDebug(level)) Log(level) 

같은 것을 사용하여 로깅에 대한 표기법을 고칠 수 ... 그리고 당신은 당신의 앱이 첫 번째 옵션 것 다음 로깅 막대한 양의를 사용할 것으로 예상되는 경우

LOG(debug) << "MyClass | my debug message" << MyExpensiveStringConversion(); 
+0

아이디어,하지만 대부분의 로거 프레임 워크에서 그 종류의 성능 트릭이 나올 것으로 예상 되었습니까? –

1

를 사용 (큰) 차이를 만들어라.
그렇지 않으면 별 문제가되지 않습니다.

로그 기능을 매크로로 래핑 할 수 있으므로 벤치 마크 목적으로 컴파일 할 때 쉽게 비활성화됩니다.

#ifdef LOG_ENABLED 
    #define LOGSTR(x) do { \ 
        debug && Log(debug) << x << MyExpensiveStringConvertion() \ 
     } while (0) 
#else 
    #define LOGSTR(x) (void)0 
#endif 
+1

'# else' 브랜치에'#define LOGSTR (x) (void) 0'을 정의하는 것이 더 좋습니다. 그렇지 않으면 다음과 같은 코드'if (something) LOGSTR ("blahblah");는 예측할 수 없습니다 (대부분의 경우 컴파일 오류가 발생합니다). 어쨌든 +1하십시오. – doc

+0

@doc'do {} (0)'이 가장 강력한 방법입니다. [여기를보십시오] (http://stackoverflow.com/questions/154136/do-while-and-if-else-statements-in-cc) -macros) –

+0

도움이되는 의견에 따라 수정되었습니다. – egur

1

맞습니다. 부울 값 (if (Debug))에 대한 간단한 테스트는 값이 싸고 규정되지 않은 Log(debug) 문에 필요한 값 비싼 문자열 'Convertion'을 건너 뜁니다. 당신은 모든 다중 호출보고있는

call ExpensiveStringConversion 
call operator << with result (maybe, depends on what class is returned by conversion) 
call operator << for whatever class Log(debug) evaluates to (with test for debug in callee) 
clean up after function call 
carry on... 

(실제로,이 LR 연관 다소 단순하고 operator<<에 대한 호출로 완전히 정확하지 않습니다입니다)

:

test some_register, Debug 
jne skip_the_debug_crap 
-- potentially lots of code here -- 

skip_the_debug_crap: 
carry on... 

대 : 코드는 기본적으로 금액 결과가 기록 될 필요가 있는지 여부에 관계없이 시간이 많이 소요됩니다. 또한 Log(debug)ExpensiveStringConversionnoexcept이 아닌 경우 잠재적 인 스택 되감기에 약간의 추가 오버 헤드가 필요합니다.

컴파일 타임 매크로를 사용할 때 제안되는 솔루션은 로깅 구성에서 시작 또는 런타임 변경이 불가능하다는 것을 의미합니다.편집에

: 의사 어셈블리와 같은 증류 (테스트, JNE, 호출)는 x86 아키텍처를 내가 내 자신의 질문에 대답 할 수 알고 있어요 모든 포스터에