с ++ получить миллисекунды с некоторой даты - PullRequest
9 голосов
/ 19 июля 2010

Мне нужен какой-то способ в c ++, чтобы отслеживать количество миллисекунд с момента выполнения программы. И мне нужна точность, чтобы быть в миллисекундах. (В моем поиске я нашел много людей, которые сказали, что включают time.h, а затем умножают вывод time() на 1000 ... это не сработает.)

Ответы [ 9 ]

8 голосов
/ 19 июля 2010

clock было предложено несколько раз.Это имеет две проблемы.Прежде всего, оно часто не имеет разрешения даже близко к миллисекунде (10-20 мс, вероятно, более распространено).Во-вторых, некоторые его реализации (например, Unix и аналогичные) возвращают время ЦП, в то время как другие (например, Windows) возвращают время стены.

Вы действительно не сказали, хотите ли вы время стены или время ЦП, котороезатрудняет дать действительно хороший ответ.В Windows вы можете использовать GetProcessTimes.Это даст вам время ядра и пользовательского процессора напрямую.Он также сообщит вам, когда был создан процесс, поэтому, если вам нужны миллисекунды времени стены с момента создания процесса, вы можете вычесть время создания процесса из текущего времени (GetSystemTime).QueryPerformanceCounter также упоминалось.У этого есть несколько своих странностей - например, в некоторых реализациях он извлекает время из счетчика цикла ЦП, поэтому его частота меняется, когда / если скорость ЦП изменяется.Другие реализации считывают данные с таймера 1.024 МГц материнской платы, который не изменяется в зависимости от скорости процессора (а условия, в которых они используются, не совсем очевидны).

В Unix выможно использовать GetTimeOfDay, чтобы просто получить время на стене с (по крайней мере, возможностью) относительно высокой точности.Если вам нужно время для процесса, вы можете использовать times или getrusage (последний является более новым и дает более полную информацию, которая также может быть более точной).

Итог: как я уже сказал в своем комментарии, нет способа получить то, что вы хотите, мобильно.Поскольку вы еще не сказали, хотите ли вы использовать процессорное время или время простоя, даже для конкретной системы, правильного ответа нет.Тот, кого вы «приняли» (clock()), обладает тем преимуществом, что доступен практически для любой системы, но то, что он возвращает, также варьируется в большинстве случаев.

1 голос
/ 20 июля 2010

Вот решение C ++ 0x и пример, почему clock() может не делать то, что вы думаете.

#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
   auto start1 = std::chrono::monotonic_clock::now();
   auto start2 = std::clock();

   sleep(1);

   for( int i=0; i<100000000; ++i);

   auto end1 = std::chrono::monotonic_clock::now();
   auto end2 = std::clock();

   auto delta1 = end1-start1;
   auto delta2 = end2-start2;

   std::cout << "chrono: " << std::chrono::duration_cast<std::chrono::duration<float>>(delta1).count() << std::endl;

   std::cout << "clock: " << static_cast<float>(delta2)/CLOCKS_PER_SEC << std::endl;
}

В моей системе это выводит:

chrono: 1.36839
clock: 0.36

Вы заметите, что clock() метод пропускает секунду. Проницательный наблюдатель может также заметить, что у clock() разрешение меньше. В моей системе это происходит с шагом 12 миллисекунд , ужасное разрешение.

Если вы не можете или не хотите использовать C ++ 0x, взгляните на Boost.DateTime ptime microsec_clock::universal_time().

1 голос
/ 19 июля 2010

Наиболее переносимым способом является использование функции clock . Обычно она сообщает о времени, когда ваша программа использовала процессор, или его приблизительное значение. Обратите внимание на следующее:

  • Разрешение не очень хорошее для систем GNU. Это действительно жаль.

  • Позаботьтесь о приведении всего к double перед выполнением делений и назначений.

  • Счетчик удерживается как 32-битное число в 32-битном GNU, что может быть довольно раздражающим для долго работающих программ.

Существуют альтернативы, использующие «время стены», которые дают лучшее разрешение, как в Windows, так и в Linux. Но, как говорится в руководстве по libc: Если вы пытаетесь оптимизировать свою программу или измерить ее эффективность, очень полезно знать, сколько процессорного времени она использует. Для этого календарное время и истекшее время бесполезны, поскольку процесс может тратить время на ожидание ввода-вывода или других процессов для использования ЦП.

1 голос
/ 19 июля 2010

Некоторое кроссплатформенное решение. Этот код был использован для какого-то теста:

#ifdef WIN32
  LARGE_INTEGER g_llFrequency = {0};
  BOOL g_bQueryResult = QueryPerformanceFrequency(&g_llFrequency);
#endif

//...

long long osQueryPerfomance()
{
#ifdef WIN32
  LARGE_INTEGER llPerf = {0};
  QueryPerformanceCounter(&llPerf);
  return llPerf.QuadPart * 1000ll / ( g_llFrequency.QuadPart / 1000ll);
#else
  struct timeval stTimeVal;
  gettimeofday(&stTimeVal, NULL);
  return stTimeVal.tv_sec * 1000000ll + stTimeVal.tv_usec;
#endif
}
1 голос
/ 19 июля 2010

Включите time.h, а затем используйте функцию clock (). Возвращает количество тактов, прошедших с момента запуска программы. Просто разделите его на «CLOCKS_PER_SEC», чтобы получить количество секунд, затем умножьте на 1000, чтобы получить количество миллисекунд.

1 голос
/ 19 июля 2010

См. std::clock()

0 голосов
/ 06 мая 2012

Вы можете попробовать этот код (получить из исходного кода шахматного движка StockFish (GPL)):

#include <iostream>
#include <stdio>

#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
    #  include <sys/time.h>
    typedef timeval sys_time_t;
    inline void system_time(sys_time_t* t) {
        gettimeofday(t, NULL);
    }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.tv_sec * 1000LL + t.tv_usec / 1000;
    }
    #else // Windows and MinGW
    #  include <sys/timeb.h>
    typedef _timeb sys_time_t;
    inline void system_time(sys_time_t* t) { _ftime(t); }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.time * 1000LL + t.millitm;
    }
#endif

struct Time {
    void restart() { system_time(&t); }
    uint64_t msec() const { return time_to_msec(t); }
    long long elapsed() const {
        return long long(current_time().msec() - time_to_msec(t));
    }
    static Time current_time() { Time t; t.restart(); return t; }
private:
    sys_time_t t;
};

int main() {
    sys_time_t t;
    system_time(&t);
    long long currentTimeMs = time_to_msec(t);
    std::cout << "currentTimeMs:" << currentTimeMs << std::endl;

    Time time = Time::current_time();
    for (int i = 0; i < 1000000; i++) {
        //Do something
    }
    long long e = time.elapsed();
    std::cout << "time elapsed:" << e << std::endl;

    getchar();  // wait for keyboard input
}
0 голосов
/ 19 июля 2010

Вам нужны время на настенных часах, время процессора или другое измерение? Кроме того, что это за платформа? Не существует универсально портативного способа получить больше точности, чем дают time() и clock(), но ...

  • в большинстве систем Unix вы можете использовать gettimeofday() и / или clock_gettime(), которые обеспечивают точность не менее микросекунды и доступ к различным таймерам;
  • Я не так хорошо знаком с Windows, но одна из этих функций , вероятно, делает то, что вы хотите.
0 голосов
/ 19 июля 2010

Это не специфично для C ++ (и не переносимо), но вы можете сделать:

SYSTEMTIME systemDT;

В Windows.

Оттуда вы можете получить доступ к каждому члену системыDT struct.

Вы можете записать время запуска программы и сравнить текущее время с записанным временем (например, systemDT против systemDTtemp).

Чтобы обновить, вы можете позвонить GetLocalTime(&systemDT);

Чтобы получить доступ к каждому члену, вы должны сделать systemDT.wHour, systemDT.wMinute, systemDT.wMilliseconds.

Для получения дополнительной информации о SYSTEMTIME .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...