HOWTO · C++
How to Measure Execution Time of a Function in C++ STL
This article introduces how to measure execution time of a function in C++
On this page
To measure elapsed time in C++, record a start time, run the function or statements you care about, and record an end time. Subtract the start from the end to get a std::chrono duration. Use std::chrono::steady_clock for intervals, then choose whether to display whole seconds, whole milliseconds, or fractional milliseconds. The result describes that run; it does not by itself establish how fast the code is in general.
Choose a clock for measuring elapsed time
The C++ <chrono> library provides clocks with different guarantees. A clock used to measure an interval should be steady: its readings do not move backward due to adjustments to the system clock. std::chrono::steady_clock is intended for measuring elapsed time and is the appropriate default for this task. By contrast, std::chrono::high_resolution_clock promises a short tick period, but the standard does not require it to be steady. A library implementation may also make it an alias for another clock. Check the documentation for your toolchain if you have a reason to choose a different clock.
Take both timestamps from the same clock. The subtraction produces a duration, so no manual conversion from clock ticks is needed. Work between the two calls is included in the interval; setup placed before the first timestamp and reporting placed after the second are excluded. Keep the measured region limited to the operation you want to understand.
Measure a function with std::chrono
For a function call, take the first timestamp immediately before the call and the second immediately after it returns. This complete example measures a function that sleeps for about three seconds. The sleep request is a minimum delay in practice: scheduling can make the elapsed interval longer. The example uses std::chrono::duration_cast to express the result as an integral number of seconds.
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>
void funcSleep() {
std::this_thread::sleep_for(std::chrono::seconds(3));
}
int main() {
const auto start = std::chrono::steady_clock::now();
funcSleep();
const auto end = std::chrono::steady_clock::now();
const auto elapsed =
std::chrono::duration_cast<std::chrono::seconds>(end - start);
std::cout << "funcSleep() elapsed time is " << elapsed.count()
<< " seconds\n";
return EXIT_SUCCESS;
}
Choose the duration unit and precision
std::chrono::duration_cast converts a duration to a chosen duration type. When the destination uses an integer representation, conversion discards the fractional part rather than rounding it. For example, an elapsed interval of 2.8 seconds converted to whole seconds has a count of 2. Use a smaller unit when whole seconds are too coarse, or use a floating-point representation when the fractional part matters.
The following variation keeps fractional milliseconds. std::chrono::duration represents a time interval as a count and a unit, and std::chrono::duration<double, std::milli> specifies a floating-point count measured in milliseconds. The printed value depends on the actual run and machine; it should not be copied as a fixed expected result.
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>
void funcSleep() {
std::this_thread::sleep_for(std::chrono::milliseconds(1250));
}
int main() {
const auto start = std::chrono::steady_clock::now();
funcSleep();
const auto end = std::chrono::steady_clock::now();
const std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "funcSleep() elapsed time is " << elapsed.count()
<< " milliseconds\n";
return EXIT_SUCCESS;
}
Measure a code block
The same pattern applies when the work is a sequence of statements instead of a function call. This example fills a vector with deterministic values and measures only the fill loop. It calculates and prints a checksum after the end timestamp so the result is used without including checksum work in the measured interval. Change the loop body to the operation you want to time, while keeping required setup outside the interval if setup is not part of that task.
#include <chrono>
#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> values(1000000);
const auto start = std::chrono::steady_clock::now();
for (std::size_t i = 0; i < values.size(); ++i) {
values[i] = static_cast<int>(i % 100);
}
const auto end = std::chrono::steady_clock::now();
const auto checksum = std::accumulate(values.begin(), values.end(), 0LL);
const std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "checksum: " << checksum << '\n';
std::cout << "fill elapsed time: " << elapsed.count() << " milliseconds\n";
return EXIT_SUCCESS;
}
Interpret results and avoid misleading timings
An elapsed duration is the time observed between two clock readings, including interruptions while the process is waiting to run. It can vary with system load, scheduling, the workload, compiler settings, and the machine. A sleep-based demonstration illustrates clock and duration APIs, but it says nothing about the speed of ordinary computation. Similarly, one run of a code block is not a reliable performance comparison.
For a meaningful comparison, keep the workload and environment controlled, run it repeatedly, and report a suitable summary rather than selecting one favorable result. Ensure the measured region does the same work in every run, and account for setup, input creation, and output consistently. A benchmarking library is useful when you need repeatable measurements and statistical summaries; that broader methodology is separate from this basic elapsed-time pattern. If a converted duration looks unexpectedly coarse, check the requested unit and whether the destination representation is integral. If a measured interval seems inconsistent, confirm that both timestamps use the same steady clock and that unrelated work is outside the timed region.