102

Windows ではclock()時間をミリ秒単位で返しますが、私が取り組んでいるこの Linux ボックスでは、最も近い 1000 に丸めるので、精度はミリ秒レベルではなく「秒」レベルになります。

クラスを使用してQtで解決策を見つけ、QTimeオブジェクトをインスタンス化し、start()それを呼び出しelapsed()てから、経過したミリ秒数を取得するために呼び出しました。

そもそもQtで作業しているので運が良かったのですが、サードパーティのライブラリに依存しないソリューションが欲しいので、

これを行う標準的な方法はありませんか?

アップデート

ブーストをお勧めしないでください..

Boost と Qt がそれを行うことができる場合、それは魔法ではなく、彼らが使用している標準的なものがあるに違いありません!

4

16 に答える 16

138
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    struct timeval start, end;

    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    printf("Elapsed time: %ld milliseconds\n", mtime);

    return 0;
}
于 2009-02-25T23:20:24.050 に答える
59

実時間は測定しclockませんのでご注意ください。つまり、プログラムに5秒かかる場合、clock必ずしも5秒は測定されませんが、それ以上(プログラムが複数のスレッドを実行する可能性があるため、リアルタイムよりも多くのCPUを消費する可能性があります)または少なくなる可能性があります。使用されたCPU時間の概算を測定します。違いを確認するには、このコードを検討してください

#include <iostream>
#include <ctime>
#include <unistd.h>

int main() {
    std::clock_t a = std::clock();
    sleep(5); // sleep 5s
    std::clock_t b = std::clock();

    std::cout << "difference: " << (b - a) << std::endl;
    return 0;
}

それは私のシステムに出力します

$ difference: 0

なぜなら、私たちがしたのはスリープ状態であり、CPU時間を使用していなかったからです。ただし、使用gettimeofdayすると、必要なものが得られます(?)

#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>

int main() {
    timeval a;
    timeval b;

    gettimeofday(&a, 0);
    sleep(5); // sleep 5s
    gettimeofday(&b, 0);

    std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
    return 0;
}

私のシステムの出力

$ difference: 5

より高い精度が必要であるがCPU時間を取得したい場合は、関数の使用を検討できgetrusageます。

于 2009-03-15T10:33:44.380 に答える
37

メソッドの開始時と終了時に gettimeofday を使用して、2 つの戻り構造体を区別することができます。次のような構造が得られます。

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

編集: 以下の 2 つのコメントが示唆するように、clock_gettime(CLOCK_MONOTONIC) が利用可能であれば、はるかに良い選択です。

編集: std::chrono::high_resolution_clock で最新の C++ を使用することもできますが、単調であるとは限りません。代わりにsteady_clock を使用してください。

于 2009-02-25T23:12:25.143 に答える
18

Boostが提供するツールもお勧めします。前述のBoostTimerを使用するか、Boost.DateTimeから何かをハックするか、サンドボックスに新しく提案されたライブラリがあります-Boost.Chrono:この最後のライブラリはTimerの代わりになり、次の機能を備えています。

  • 以下を含むC++0x標準ライブラリのタイムユーティリティ:
    • クラステンプレートduration
    • クラステンプレートtime_point
    • 時計:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • timertypedefを使用した クラステンプレート:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • プロセスクロックとタイマー:
    • process_clock、実際の時間、ユーザーCPU時間、およびシステムCPU時間をキャプチャします。
    • process_timer、経過した実時間、ユーザーCPU時間、およびシステムCPU時間をキャプチャします。
    • run_timer、|process_timer|の便利なレポート 結果。
  • C++0x標準ライブラリのコンパイル時の有理演算。

機能リストのソースは次のとおりです

于 2009-02-25T23:33:34.487 に答える
13

CTT の回答Timerに基づいてクラスを作成しました。次の方法で使用できます。

Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);

その実装は次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;

class Timer {
private:

    timeval startTime;

public:

    void start(){
        gettimeofday(&startTime, NULL);
    }

    double stop(){
        timeval endTime;
        long seconds, useconds;
        double duration;

        gettimeofday(&endTime, NULL);

        seconds  = endTime.tv_sec  - startTime.tv_sec;
        useconds = endTime.tv_usec - startTime.tv_usec;

        duration = seconds + useconds/1000000.0;

        return duration;
    }

    static void printTime(double duration){
        printf("%5.6f seconds\n", duration);
    }
};
于 2010-09-09T14:55:49.663 に答える
9

コードを古いユニックスに移植する必要がない場合は、clock_gettime() を使用できます。これにより、ナノ秒単位の時間が得られます(プロセッサがその解像度をサポートしている場合)。POSIXですが、2001年からです。

于 2009-02-26T03:17:26.663 に答える
4

clock() の解像度はかなりお粗末です。ミリ秒レベルで時間を測定する場合は、この質問で説明されているように、clock_gettime() を使用することもできます。

(Linux では -lrt でリンクする必要があることに注意してください)。

于 2009-03-15T07:32:59.307 に答える
4

C++11 を使用すると、次のstd::chrono::high_resolution_clockことができます。

#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    std::chrono::milliseconds three_milliseconds{3};

    auto t1 = Clock::now();
    std::this_thread::sleep_for(three_milliseconds);
    auto t2 = Clock::now();

    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds" << std::endl;
}

出力:

Delta t2-t1: 3 milliseconds

デモへのリンク: http://cpp.sh/2zdtu

于 2016-06-07T08:21:25.047 に答える
2

clock() は、Linux ではミリ秒または秒を返しません。通常、Linux システムでは clock() はマイクロ秒を返します。clock() によって返された値を解釈する適切な方法は、それを CLOCKS_PER_SEC で割り、経過した時間を把握することです。

于 2009-02-25T23:07:12.537 に答える
1

POSIX 標準clockでは、CLOCKS_PER_SEC シンボルに関して定義された戻り値があり、実装はこれを便利な方法で自由に定義できます。Linux では、この関数でうまくいきましたtimes()

于 2009-02-25T23:08:47.977 に答える
1

gettimeofday - 問題は、ハードウェア クロック (NTP など) を変更すると値が小さくなる可能性があることです Boost - このプロジェクトでは使用できません clock() - 通常は 4 バイトの整数を返します。しばらくすると、負の数が返されます。

私は独自のクラスを作成し、10 ミリ秒ごとに更新することを好みます。そのため、この方法はより柔軟であり、サブスクライバーを持つように改善することもできます。

class MyAlarm {
static int64_t tiempo;
static bool running;
public:
static int64_t getTime() {return tiempo;};
static void callback( int sig){
    if(running){
        tiempo+=10L;
    }
}
static void run(){ running = true;}
};

int64_t MyAlarm::tiempo = 0L;
bool MyAlarm::running = false;

それを更新するには、setitimer を使用します。

int main(){
struct sigaction sa; 
struct itimerval timer; 

MyAlarm::run();
memset (&sa, 0, sizeof (sa)); 
sa.sa_handler = &MyAlarm::callback; 

sigaction (SIGALRM, &sa, NULL); 


timer.it_value.tv_sec = 0; 
timer.it_value.tv_usec = 10000; 



timer.it_interval.tv_sec = 0; 
timer.it_interval.tv_usec = 10000; 


setitimer (ITIMER_REAL, &timer, NULL); 
.....

setitimer と ITIMER_VIRTUAL および ITIMER_REAL を見てください。

alarm または ualarm 関数を使用しないでください。プロセスが大変な作業を行うと、精度が低下します。

于 2012-09-04T12:25:45.917 に答える
1

これは動作するはずです... Macでテスト済み...

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

int main() {
        struct timeval tv;
        struct timezone tz;
        struct tm *tm;
        gettimeofday(&tv,&tz);
        tm=localtime(&tv.tv_sec);
        printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}

ええ...2回実行して減算...

于 2009-02-25T23:18:51.010 に答える
0

更新として、Windowsではclock()が実時間(CLOCKS_PER_SECの精度で)を測定しているように見えます

 http://msdn.microsoft.com/en-us/library/4e2ess30(VS.71).aspx

Linuxでは、現在のプロセスで使用されているコア全体のCPU時間を測定します。

http://www.manpagez.com/man/3/clock

および(表示され、元のポスターに記載されているように)実際にはCLOCKS_PER_SECよりも精度が低くなりますが、これはLinuxの特定のバージョンによって異なる場合があります

于 2010-08-11T14:29:40.603 に答える
0

gettimeofday() を使用しない Hola Soy メソッドが気に入っています。管理者がタイムゾーンを変更した実行中のサーバーで私に起こりました。時計が更新され、同じ (正しい) ローカル値が表示されるようになりました。これにより、関数 time() および gettimeofday() が 2 時間シフトし、一部のサービスのすべてのタイムスタンプが動かなくなりました。

于 2014-10-09T12:27:33.527 に答える
0

C++を使ってクラスを書きましたtimeb

#include <sys/timeb.h>
class msTimer 
{
public:
    msTimer();
    void restart();
    float elapsedMs();
private:
    timeb t_start;
};

メンバー関数:

msTimer::msTimer() 
{ 
    restart(); 
}

void msTimer::restart() 
{ 
    ftime(&t_start); 
}

float msTimer::elapsedMs() 
{
    timeb t_now;
    ftime(&t_now);
    return (float)(t_now.time - t_start.time) * 1000.0f +
           (float)(t_now.millitm - t_start.millitm);
}

使用例:

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) 
{
    msTimer t;
    for (int i = 0; i < 5000000; i++)
        ;
    std::cout << t.elapsedMs() << endl;
    return 0;
}

私のコンピューターの出力は「19」です。msTimerクラスの精度はミリ秒単位です。上記の使用例では、-loop によって消費された合計実行時間forが追跡されます。今回は、main()マルチタスクによるオペレーティング システムの実行コンテキストの切り替えが含まれていました。

于 2016-01-23T04:04:28.030 に答える
0

私はシンプルさからBoost Timer ライブラリを好みますが、サードパーティのライブラリを使用したくない場合は、clock() を使用するのが合理的です。

于 2009-02-25T23:18:35.490 に答える