2014-10-01 3 views
1

파이썬에서 오는 것은 C++ 코드에서 여러 함수 호출을 시간 측정하는 방법을 찾으려고합니다. 지금까지 나는 이것을 사용하고있다.여러 함수 호출의 타이밍

void my_func(/*some args*/) { 
    clock_t t_begin = std::clock(); 
    // code 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

그러나 이것은 매우 반복적입니다. 그리고 내가 쓸 수 있도록하는 기능 래퍼처럼 뭔가를하고 싶은 : C++에서 이것을 달성하기 위해 어떤 방법이 있나요

timer(compute_a, a, b) 
timer(compute_b, b, c) 

:

void timer(func, *args) { 
    clock_t t_begin = std::clock(); 
    func(*args) 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

처럼 사용할 수있는?

PS : 나는 이렇게 내가 프로파일 플래그로 내 코드를 다시 컴파일하고 Valgrind의 또는 내가 과거에이 패턴을 사용한 다른 도구

+0

[C++ 11]을 사용하는 경우 [variadic template] (http://en.wikipedia.org/wiki/Variadic_template)을 만들 수 있다고 생각합니다. (http://en.wikipedia.org/wiki/C++11). 또는 단순히 [preprocessor] (http://en.wikipedia.org/wiki/C_preprocessor) 매크로. –

답변

4

하는 가변 인자 템플릿을 사용하면 같은 일을 할 수

template <typename F, typename ... Ts> 
void timer(F f, Ts&&...args) { 
    clock_t t_begin = std::clock(); 
    f(std::forward<Ts>(args)...); 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

그러나 단순히

template <typename F> 
void timer(F f) { 
    clock_t t_begin = std::clock(); 
    f(); 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

가 작업을 수행하고 인수를 전달해야 할 때 람다 캡처를 통과해야합니다

timer([&](){ compute_b(b, c);}); 
0

로 스틱 싶지 않다, 생산 실행의 타이밍이 필요합니다. 이것은 한 번의 호출로 소요 된 시간이 아닌 프로그램의 전체 수명 동안 기능에 소요 된 총 시간을 포착합니다.

struct FunctionTimer 
{ 
    FunctionTimer(std::string const& fname) : fname_(fname), totalTime_(0) {} 

    ~FunctionTimer() 
    { 
     std::cout << "Total time in " << fname_ << ": " << totalTime_ << std::endl; 
    } 

    std::string fname_; 
    double totalTime_; 
}; 

struct TimeAccumulator 
{ 
    TimeAccumulator(FunctionTimer& timer) : timer_(timer), begin_(std::clock()) {} 
    ~TimeAccumulator() 
    { 
     clock_t end = std::clock(); 
     double elapsed_secs = double(end - begin_)/CLOCKS_PER_SEC; 
     timer_.totalTime_ += elapsed_secs; 
    } 

    clock_t begin_; 
    FunctionTimer& timer_; 
}; 

void my_func(/*some args*/) 
{ 
    static FunctionTimer timer("my_func"); 
    TimeAccumulator acc(timer); 

    // code 
} 

당신이 목적 타이밍에 대한 래퍼 함수를 ​​작성하고 훼손되지 않은 기능의 나머지 부분을 남겨하려는 경우, 일부 템플릿 마법 트릭을 할. 어떻게 함수 템플릿을 구현할 수 있는지에 대한 세부적인 사항을 생각해야합니다.

+0

하지만 여전히'timer (my_func) '를 통해 모든 함수를 호출하는 대신 모든 함수를 수정해야합니다. – greole

+0

@ greole, 그 방법은 내가 과거에 사용 해왔다. 필자는 두 줄의 코드를 컴파일 단위로 컴파일 할 때 매크로에서 사용/사용 안 함으로 줄 바꿈했습니다. –

관련 문제