Подтвердить что ты не робот

Получение точного времени выполнения на С++ (микросекунды)

Я хочу получить точное время выполнения в микросекундах моей программы, реализованной на С++. Я попытался получить время выполнения с помощью clock_t, но это не точно.

4b9b3361

Ответ 1

Если вы используете С++ 11 или новее, вы можете использовать std::chrono::high_resolution_clock.

Простой вариант:

auto start = std::chrono::high_resolution_clock::now();
...
auto elapsed = std::chrono::high_resolution_clock::now() - start;

long long microseconds = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();

Это решение имеет то преимущество, что оно переносимо.

Ответ 2

Если вы посмотрите, сколько времени занимает выполнение вашей программы из оболочки Unix, используйте Linux time, как показано ниже,

time ./a.out 

real    0m0.001s
user    0m0.000s
sys     0m0.000s

Во-вторых, если вы хотите, чтобы время выполнения ряда операторов в коде программы (C) попыталось использовать gettimeofday(), как показано ниже,

#include <sys/time.h>
struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* Program code to execute here */
gettimeofday(&tv2, NULL);
printf("Time taken in execution = %f seconds\n",
     (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
     (double) (tv2.tv_sec - tv1.tv_sec));

Ответ 3

Новая библиотека C++ 11 std::chrono - одна из самых сложных куч, которую я когда-либо видел или пытался выяснить, как ее использовать, но, по крайней мере, она кроссплатформенная!

Итак, если вы хотите упростить его и сделать его более "C-подобным", в том числе удалить все, что он делает с типобезопасным классом, то здесь 3 простых и очень простых в использовании функции для получения меток времени в миллисекундах., микросекунды и наносекунды... это заняло у меня всего 12 часов *:

#include <chrono>

// NB: ALL OF THESE 3 FUNCTIONS BELOW USE SIGNED VALUES INTERNALLY AND WILL EVENTUALLY OVERFLOW (AFTER 200+ YEARS OR
// SO), AFTER WHICH POINT THEY WILL HAVE *SIGNED OVERFLOW*, WHICH IS UNDEFINED BEHAVIOR (IE: A BUG) FOR C/C++.
// But...that ok...this "bug" is designed into the C++11 specification, so whatever. Your machine won't run for 200
// years anyway...

// Get time stamp in milliseconds.
uint64_t millis()
{
    uint64_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::
                  now().time_since_epoch()).count();
    return ms; 
}

// Get time stamp in microseconds.
uint64_t micros()
{
    uint64_t us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::
                  now().time_since_epoch()).count();
    return us; 
}

// Get time stamp in nanoseconds.
uint64_t nanos()
{
    uint64_t ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::
                  now().time_since_epoch()).count();
    return ns; 
}

* (Извините, я был скорее разработчиком встраиваемых систем, чем обычным программистом, поэтому все эти высокоуровневые, абстрактные статические элементы внутри класса в пространстве имен внутри пространства имен в пространстве имен сбивают с толку меня. Не волнуйтесь, я поправлюсь.)

И вот несколько ссылок:

Ответ 4

Если вы находитесь в Windows, вы можете использовать QueryPerformanceCounter

См. Как использовать функцию QueryPerformanceCounter для временного кода в Visual С++

__int64 ctr1 = 0, ctr2 = 0, freq = 0;
int acc = 0, i = 0;

// Start timing the code.
if (QueryPerformanceCounter((LARGE_INTEGER *)&ctr1)!= 0)
{
    // Code segment is being timed.
    for (i=0; i<100; i++) acc++;

    // Finish timing the code.
    QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);

    Console::WriteLine("Start Value: {0}",ctr1.ToString());
    Console::WriteLine("End Value: {0}",ctr2.ToString());

    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);

    Console::WriteLine(S"QueryPerformanceCounter minimum resolution: 1/{0} Seconds.",freq.ToString());
    // In Visual Studio 2005, this line should be changed to:     Console::WriteLine("QueryPerformanceCounter minimum resolution: 1/{0} Seconds.",freq.ToString()); 
    Console::WriteLine("100 Increment time: {0} seconds.",((ctr2 - ctr1) * 1.0 / freq).ToString());
}
else
{
    DWORD dwError = GetLastError();
    Console::WriteLine(S"Error value = {0}",dwError.ToString());// In Visual Studio 2005, this line should be changed to: Console::WriteLine("Error value = {0}",dwError.ToString());
}

// Make the console window wait.
Console::WriteLine();
Console::Write("Press ENTER to finish.");
Console::Read();

return 0;

Вы можете поместить его вокруг вызова CreateProcess(...) и WaitForSingleObject(...) для всего жизненного цикла процесса, в противном случае вокруг основной функции для вашего кода.