[c++] 경과 시간을 쉽게 측정

프로그램의 다양한 지점을 측정 하기 위해 time () 을 사용하려고합니다 .

내가 이해하지 못하는 것은 이전과 이후의 값이 같은 이유입니다. 나는 이것이 내 프로그램을 프로파일 링하는 가장 좋은 방법은 아니라는 것을 이해하고 있습니다.

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));

나는 시도했다 :

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);

결과는 **time taken = 0 26339어떻게 읽 습니까? 26,339 나노초 = 26.3 밀리 초를 의미합니까?

무엇에 대해 **time taken = 4 45025, 그 평균 사초 25 밀리 초를합니까?



답변

//***C++11 Style:***
#include <chrono>

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;


답변

#include <ctime>

void f() {
  using namespace std;
  clock_t begin = clock();

  code_to_time();

  clock_t end = clock();
  double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
}

time()기능은 1 초 이내에만 정확하지만 CLOCKS_PER_SEC1 초 내에 “시계”가 있습니다. 과도하게 단순화 되었더라도 쉽고 휴대용 측정입니다.


답변

타이머 구조를 통해 호출 함으로써 시간 측정 메커니즘을 추상화하고 최소한의 추가 코드로 각 호출 가능 런타임을 측정 할 수 있습니다 . 또한 컴파일 타임 에 타이밍 유형 (밀리 초, 나노초 등)을 매개 변수화 할 수 있습니다 .

Loki Astari 의 검토 와 다양한 템플릿 사용 제안에 감사합니다 .
이것은 왜 전달 함수 호출이다.

#include <iostream>
#include <chrono>

template<typename TimeT = std::chrono::milliseconds>
struct measure
{
    template<typename F, typename ...Args>
    static typename TimeT::rep execution(F&& func, Args&&... args)
    {
        auto start = std::chrono::steady_clock::now();
        std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
        auto duration = std::chrono::duration_cast< TimeT> 
                            (std::chrono::steady_clock::now() - start);
        return duration.count();
    }
};

int main() {
    std::cout << measure<>::execution(functor(dummy)) << std::endl;
}

Demo

Howard Hinnant 의 의견에 따르면 , 크로노 시스템을 벗어나지 않는 것이 가장 좋습니다. 따라서 위의 클래스는 사용자에게 count추가 정적 메소드를 제공하여 수동으로 호출하도록 선택할 수 있습니다 (C ++ 14에 표시됨)

template<typename F, typename ...Args>
static auto duration(F&& func, Args&&... args)
{
    auto start = std::chrono::steady_clock::now();
    std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
    return std::chrono::duration_cast<TimeT>(std::chrono::steady_clock::now()-start);
} 

// call .count() manually later when needed (eg IO)
auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2.0;

고객에게 가장 유용합니다.

“I / O 이전에 여러 기간을 사후 처리해야합니다 (예 : 평균)”


전체 코드는 여기에서 찾을 수 있습니다 . 크로노를 기반으로 한 벤치마킹 도구 를 구축하려는 시도 는 여기 에 기록 됩니다 .


C ++ 17 std::invoke이 사용 가능한 경우 호출 가능한 호출은 다음 execution과 같이 수행 할 수 있습니다.

invoke(forward<decltype(func)>(func), forward<Args>(args)...);

멤버 함수에 대한 포인터 인 콜 러블을 제공합니다.


답변

귀하의 질문에서 알 수 있듯이 일부 코드 실행 후 경과 시간을 알고 싶어하는 것 같습니다. 결과를 두 번째로 편안하게 볼 수 있다고 생각합니다. 그렇다면 difftime()아래 표시된대로 기능을 사용해보십시오 . 이것이 문제를 해결하기를 바랍니다.

#include <time.h>
#include <stdio.h>

time_t start,end;
time (&start);
.
.
.
<your code>
.
.
.
time (&end);
double dif = difftime (end,start);
printf ("Elasped time is %.2lf seconds.", dif );


답변

Windows 전용 : (이 답변을 게시 한 후 Linux 태그가 추가되었습니다)

GetTickCount () 를 사용 하여 시스템이 시작된 이후 경과 된 시간 (밀리 초 ) 을 얻을 수 있습니다 .

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();


답변

time(NULL)1970 년 1 월 1 일 이후 00:00에 경과 된 시간 (초)을 리턴합니다 ( Epoch ). 따라서 두 값의 차이는 처리 시간 (초)입니다.

int t0 = time(NULL);
doSomthing();
doSomthingLong();
int t1 = time(NULL);

printf ("time = %d secs\n", t1 - t0);

을 사용 getttimeofday()하면 현재 시간을 초 단위 time()와 마이크로 초 단위 로 반환하여 더 나은 결과를 얻을 수 있습니다 .


답변

time (NULL) 함수는 1970 년 1 월 1 일 이후 00:00에 경과 된 시간 (초)을 반환합니다. 그리고 그 함수는 프로그램에서 다른 시간에 호출되기 때문에 C ++에서는 항상 다른
시간이됩니다