Getting an accurate execution time in C++ (micro seconds)
If you are using c++11 or later you could use std::chrono::high_resolution_clock
.
A simple use case :
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();
This solution has the advantage of being portable.
Beware that micro-benchmarking is hard. It's very easy to measure the wrong thing (like your benchmark optimizing away), or to include page-faults in your timed region, or fail to account for CPU frequency idle vs. turbo.
See Idiomatic way of performance evaluation? for some general tips, e.g. sanity check by testing the other one first and see if that changes which one appears faster.
How to get execution time of c program?
Contrary to popular belief, the clock()
function retrieves CPU time, not elapsed clock time as the name confusingly may induce people to believe.
Here is the language from the C Standard:
7.27.2.1 The
clock
functionSynopsis
#include <time.h>
clock_t clock(void);
Description
The
clock
function determines the processor time used.Returns
The
clock
function returns the implementation’s best approximation to the processor time used by the program since the beginning of an implementation-defined era related only to the program invocation. To determine the time in seconds, the value returned by the clock function should be divided by the value of the macroCLOCKS_PER_SEC
. If the processor time used is not available, the function returns the value(clock_t)(−1)
. If the value cannot be represented, the function returns an unspecified value.
To retrieve the elapsed time, you should use one of the following:
- the
time()
function with a resolution of 1 second - the
timespec_get()
function which may be more precise, but might not be available on all systems - the
gettimeofday()
system call available on linux systems - the
clock_gettime()
function.
See What specifically are wall-clock-time, user-cpu-time, and system-cpu-time in UNIX? for more information on this subject.
Here is a modified version using gettimeoday()
:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
int main() {
struct timeval start, end;
gettimeofday(&start, NULL);
sleep(3);
gettimeofday(&end, NULL);
double time_taken = end.tv_sec + end.tv_usec / 1e6 -
start.tv_sec - start.tv_usec / 1e6; // in seconds
printf("time program took %f seconds to execute\n", time_taken);
return 0;
}
Output:
time program took 3.005133 seconds to execute
Get a timestamp in C in microseconds?
You need to add in the seconds, too:
unsigned long time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;
Note that this will only last for about 232/106 =~ 4295 seconds, or roughly 71 minutes though (on a typical 32-bit system).
Execution time of C program
CLOCKS_PER_SEC
is a constant which is declared in <time.h>
. To get the CPU time used by a task within a C application, use:
clock_t begin = clock();
/* here, do your time-consuming job */
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
Note that this returns the time as a floating point type. This can be more precise than a second (e.g. you measure 4.52 seconds). Precision depends on the architecture; on modern systems you easily get 10ms or lower, but on older Windows machines (from the Win98 era) it was closer to 60ms.
clock()
is standard C; it works "everywhere". There are system-specific functions, such as getrusage()
on Unix-like systems.
Java's System.currentTimeMillis()
does not measure the same thing. It is a "wall clock": it can help you measure how much time it took for the program to execute, but it does not tell you how much CPU time was used. On a multitasking systems (i.e. all of them), these can be widely different.
c/c++ microsecond timestamp
The typical printing format for sub-second times uses the decimal indicator (.
in many locales) and so 59 and some seconds might look like 59.00013.
The micro
variable you created takes the current microsecond count, multiplies it by 1000000 then adds the current microsecond count again; I expect that you intend to either use the microsecond count alone, or together with the count of seconds:
unsigned long micro = curTime.tv_usec*(uint64_t)1000000+curTime.tv_usec;
should be written as
unsigned long micro = curTime.tv_sec*(uint64_t)1000000+curTime.tv_usec;
to get seconds and microseconds together in the same number.
To write this into your output, you might consider changing the line
sprintf(currentTime2, "%s:%Lu", buffer, micro);
to
sprintf(currentTime2, "%s.%Lu", buffer, curTime.tv_usec);
Using the altered micro
definition, you can also output
sprintf(currentSeconds, "%.6f", micro / 1000000);
Measuring execution time of a function in C++
It is a very easy-to-use method in C++11. You have to use std::chrono::high_resolution_clock
from <chrono>
header.
Use it like so:
#include <chrono>
/* Only needed for the sake of this example. */
#include <iostream>
#include <thread>
void long_operation()
{
/* Simulating a long, heavy operation. */
using namespace std::chrono_literals;
std::this_thread::sleep_for(150ms);
}
int main()
{
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;
auto t1 = high_resolution_clock::now();
long_operation();
auto t2 = high_resolution_clock::now();
/* Getting number of milliseconds as an integer. */
auto ms_int = duration_cast<milliseconds>(t2 - t1);
/* Getting number of milliseconds as a double. */
duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_int.count() << "ms\n";
std::cout << ms_double.count() << "ms\n";
return 0;
}
This will measure the duration of the function long_operation
.
Possible output:
150ms
150.068ms
Working example: https://godbolt.org/z/oe5cMd
Is there a way to measure time up to micro seconds using C standard library?
The precision of the measurement depends on the operating system, unfortunately.
How to measure time in milliseconds using ANSI C?
There is no ANSI C function that provides better than 1 second time resolution but the POSIX function gettimeofday
provides microsecond resolution. The clock function only measures the amount of time that a process has spent executing and is not accurate on many systems.
You can use this function like this:
struct timeval tval_before, tval_after, tval_result;
gettimeofday(&tval_before, NULL);
// Some code you want to time, for example:
sleep(1);
gettimeofday(&tval_after, NULL);
timersub(&tval_after, &tval_before, &tval_result);
printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
This returns Time elapsed: 1.000870
on my machine.
What is the precision of the gettimeofday function?
The average microseconds passed between consecutive calls to gettimeofday
is usually less than one - on my machine it is somewhere between 0.05 and 0.15.
Modern CPUs usually run at GHz speeds - i.e. billions of instructions per second, and so two consecutive instructions should take on the order of nanoseconds, not microseconds (obviously two calls to a function like gettimeofday
is more complex than two simple opcodes, but it should still take on the order of tens of nanoseconds and not more).
But you are performing a division of int
s - dividing (current_time[MAX_TIMES - 1].tv_usec - current_time[0].tv_usec)
by MAX_TIMES
- which in C will return an int
as well, in this case 0.
To get the real measurement, divide by (double)MAX_TIMES
(and print the result as a double):
printf("the average time of a gettimeofday function call is: %f us\n", (current_time[MAX_TIMES - 1].tv_usec - current_time[0].tv_usec) / (double)MAX_TIMES);
As a bonus - on Linux systems the reason gettimeofday
is so fast (you might imagine it to be a more complex function, calling into the kernel and incurring the overhead of a syscall) is thanks to a special feature called vdso which lets the kernel provide information to user space without going through the kernel at all.
Related Topics
How to Cout a Float Number with N Decimal Places
False Positive with Is_Copy_Constructible on Vector<Unique_Ptr>
How to Use Std::Sort with a Vector of Structures and Compare Function
Issuing System Commands in Linux from C, C++
Benchmarking (Python VS. C++ Using Blas) and (Numpy)
Should I Learn C Before Learning C++
How to Set Up Googletest as a Shared Library on Linux
How to Identify Platform/Compiler from Preprocessor MACros
What Do Each Memory_Order Mean
In C++ , What's So Special About "_Move_H"
Why Can't I Write to a String Literal While I *Can* Write to a String Object
Why Stdfax.H Should Be the First Include on Mfc Applications
C++ Qt Signal and Slot Not Firing
Why Does Gcc Generate 15-20% Faster Code If I Optimize for Size Instead of Speed
How to Get a List of Video Capture Devices (Web Cameras) on Linux ( Ubuntu )? (C/C++)