[c++] C ++에서 코드 조각의 실행 시간을 계산하는 방법

C ++ 코드 조각의 실행 시간을 초 단위로 계산해야합니다. Windows 또는 Unix 시스템에서 작동해야합니다.

이 작업을 수행하기 위해 다음 코드를 사용합니다. (이전에 가져 오기)

clock_t startTime = clock();
// some code here
// to compute its execution duration in runtime
cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " seconds." << endl;

그러나 a = a + 1과 같은 작은 입력이나 짧은 문장의 경우 “0 초”결과를 얻습니다. 0.0000001 초 정도가 될 것 같아요.

System.nanoTime()이 경우 Java에서 잘 작동 한다는 것을 기억합니다 . 그러나 clock()C ++의 기능에서 동일한 기능을 얻을 수 없습니다 .

해결책이 있습니까?



답변

내가 작성한이 기능을 사용할 수 있습니다. 을 호출 GetTimeMs64()하면 시스템 시계를 사용하는 유닉스 에포크 이후 경과 된 밀리 초 수를 반환합니다 time(NULL).

Windows와 Linux 모두에서 작동합니다. 스레드로부터 안전합니다.

세분성은 Windows에서 15ms입니다. Linux에서는 구현에 따라 다르지만 일반적으로 15ms입니다.

#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#include <ctime>
#endif

/* Remove if already defined */
typedef long long int64; typedef unsigned long long uint64;

/* Returns the amount of milliseconds elapsed since the UNIX epoch. Works on both
 * windows and linux. */

uint64 GetTimeMs64()
{
#ifdef _WIN32
 /* Windows */
 FILETIME ft;
 LARGE_INTEGER li;

 /* Get the amount of 100 nano seconds intervals elapsed since January 1, 1601 (UTC) and copy it
  * to a LARGE_INTEGER structure. */
 GetSystemTimeAsFileTime(&ft);
 li.LowPart = ft.dwLowDateTime;
 li.HighPart = ft.dwHighDateTime;

 uint64 ret = li.QuadPart;
 ret -= 116444736000000000LL; /* Convert from file time to UNIX epoch time. */
 ret /= 10000; /* From 100 nano seconds (10^-7) to 1 millisecond (10^-3) intervals */

 return ret;
#else
 /* Linux */
 struct timeval tv;

 gettimeofday(&tv, NULL);

 uint64 ret = tv.tv_usec;
 /* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
 ret /= 1000;

 /* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
 ret += (tv.tv_sec * 1000);

 return ret;
#endif
}


답변

마이크로 초 (UNIX, POSIX 등)를 사용하는 또 다른 작업 예제가 있습니다.

    #include <sys/time.h>
    typedef unsigned long long timestamp_t;

    static timestamp_t
    get_timestamp ()
    {
      struct timeval now;
      gettimeofday (&now, NULL);
      return  now.tv_usec + (timestamp_t)now.tv_sec * 1000000;
    }

    ...
    timestamp_t t0 = get_timestamp();
    // Process
    timestamp_t t1 = get_timestamp();

    double secs = (t1 - t0) / 1000000.0L;

다음은이를 코딩 한 파일입니다.

https://github.com/arhuaco/junkcode/blob/master/emqbit-bench/bench.c


답변

다음은 만족스러운 해상도를 제공하는 C ++ 11의 간단한 솔루션입니다.

#include <iostream>
#include <chrono>

class Timer
{
public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const {
        return std::chrono::duration_cast<second_>
            (clock_::now() - beg_).count(); }

private:
    typedef std::chrono::high_resolution_clock clock_;
    typedef std::chrono::duration<double, std::ratio<1> > second_;
    std::chrono::time_point<clock_> beg_;
};

또는 * nix에서, C ++ 03의 경우

#include <iostream>
#include <ctime>

class Timer
{
public:
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }

    double elapsed() {
        clock_gettime(CLOCK_REALTIME, &end_);
        return end_.tv_sec - beg_.tv_sec +
            (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
    }

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }

private:
    timespec beg_, end_;
};

다음은 사용 예입니다.

int main()
{
    Timer tmr;
    double t = tmr.elapsed();
    std::cout << t << std::endl;

    tmr.reset();
    t = tmr.elapsed();
    std::cout << t << std::endl;

    return 0;
}

에서 https://gist.github.com/gongzhitaao/7062087


답변

#include <boost/progress.hpp>

using namespace boost;

int main (int argc, const char * argv[])
{
  progress_timer timer;

  // do stuff, preferably in a 100x loop to make it take longer.

  return 0;
}

progress_timer범위를 벗어나 그것의 창조 이후 경과 된 시간을 인쇄합니다.

업데이트 : 다음은 Boost없이 작동하는 버전입니다 (macOS / iOS에서 테스트 됨).

#include <chrono>
#include <string>
#include <iostream>
#include <math.h>
#include <unistd.h>

class NLTimerScoped {
private:
    const std::chrono::steady_clock::time_point start;
    const std::string name;

public:
    NLTimerScoped( const std::string & name ) : name( name ), start( std::chrono::steady_clock::now() ) {
    }


    ~NLTimerScoped() {
        const auto end(std::chrono::steady_clock::now());
        const auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count();

        std::cout << name << " duration: " << duration_ms << "ms" << std::endl;
    }

};

int main(int argc, const char * argv[]) {

    {
        NLTimerScoped timer( "sin sum" );

        float a = 0.0f;

        for ( int i=0; i < 1000000; i++ ) {
            a += sin( (float) i / 100 );
        }

        std::cout << "sin sum = " << a << std::endl;
    }



    {
        NLTimerScoped timer( "sleep( 4 )" );

        sleep( 4 );
    }



    return 0;
}


답변

Windows는 QueryPerformanceCounter () 함수를 제공하고 Unix에는 gettimeofday ()가 있습니다. 두 함수 모두 최소 1 마이크로 초 차이를 측정 할 수 있습니다.


답변

일부 프로그램에서는 이러한 목적으로 RDTS 를 사용 했습니다 . RDTSC는 시간에 관한 것이 아니라 프로세서 시작부터 사이클 수에 관한 것입니다. 초 단위로 결과를 얻으려면 시스템에서 보정해야하지만 성능을 평가하고 싶을 때 정말 편리합니다. 사이클 수를 다시 초로 변경하지 않고 직접 사용하는 것이 훨씬 좋습니다.

(위의 링크는 프랑스어 위키피디아 페이지이지만 C ++ 코드 샘플이 있으며 영어 버전은 여기에 있습니다 )


답변

시스템에서 시간 정보를 얻기 위해 표준 라이브러리 함수를 사용하는 것이 좋습니다.

더 미세한 해결을 원하면 더 많은 실행 반복을 수행하십시오. 프로그램을 한 번 실행하고 샘플을 얻는 대신 1000 회 이상 실행하십시오.