xtd 0.2.0
xtd::diagnostics::stopwatch Class Reference

Definition

Provides a set of methods and properties that you can use to accurately measure elapsed time.

class core_export_ stopwatch : public xtd::object
Inheritance
xtd::objectxtd::diagnostics::stopwatch
Header
#include <xtd/diagnostics/stopwatch>
Namespace
xtd::diagnostics
Library
xtd.core
Remarks
A xtd::diagnostics::stopwatch instance can measure elapsed time for one interval, or the total of elapsed time across multiple intervals. In a typical xtd::diagnostics::stopwatch scenario, you call the xtd::diagnostics::stopwatch::start method, then eventually call the xtd::diagnostics::stopwatch::stop method, and then you check elapsed time using the xtd::diagnostics::stopwatch::elapsed property.
A xtd::diagnostics::stopwatch instance is either running or stopped; use xtd::diagnostics::stopwatch::is_running to determine the current state of a xtd::diagnostics::stopwatch::. Use xtd::diagnostics::stopwatch::start to begin measuring elapsed time; use xtd::diagnostics::stopwatch::stop to stop measuring elapsed time. Query the elapsed time value through the properties xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_milliseconds, or xtd::diagnostics::stopwatch::elapsed_ticks. You can query the elapsed time properties while the instance is running or stopped. The elapsed time properties steadily increase while the xtd::diagnostics::stopwatch is running; they remain constant when the instance is stopped.
By default, the elapsed time value of a xtd::diagnostics::stopwatch:: instance equals the total of all measured time intervals. Each call to xtd::diagnostics::stopwatch::start begins counting at the cumulative elapsed time; each call to xtd::diagnostics::stopwatch::stop ends the current interval measurement and freezes the cumulative elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in an existing xtd::diagnostics::stopwatch instance.
The xtd::diagnostics::stopwatch measures elapsed time by counting timer ticks in the underlying timer mechanism. If the installed hardware and operating system support a high-resolution performance counter, then the xtd::diagnostics::stopwatch:: class uses that counter to measure elapsed time. Otherwise, the xtd::diagnostics::stopwatch class uses the system timer to measure elapsed time. Use the xtd::diagnostics::stopwatch::frequency and xtd::diagnostics::stopwatch::is_high_resolution fields to determine the precision and resolution of the xtd::diagnostics::stopwatch timing implementation.
The xtd::diagnostics::stopwatch class assists the manipulation of timing-related performance counters. Specifically, the xtd::diagnostics::stopwatch::frequency field and xtd::diagnostics::stopwatch::get_timestamp method can be used in place of the Win32 APIs QueryPerformanceFrequency and QueryPerformanceCounter.
Examples
The following example demonstrates how to use the xtd::diagnostics::stopwatch class to determine the execution time for an application.
#include <xtd/diagnostics/stopwatch>
#include <xtd/console>
#include <limits>
using namespace std;
using namespace xtd;
using namespace xtd::diagnostics;
class operations_timer {
public:
static void display_timer_properties() {
// Display the timer frequency and resolution.
console::write_line("Operations timed using the system's high-resolution performance counter.");
else
console::write_line("Operations timed using the standard date time.");
console::write_line(" Timer frequency in ticks per second = {0}", frequency);
auto nanosec_per_tick = (1000l * 1000l * 1000l) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
auto nanosec_per_tick = (1000l * 1000l * 1000l) / stopwatch::frequency();
constexpr auto num_iterations = 10000;
// Define the operation title names.
auto operation_names = vector {"Operation: parse<int>(\"0\")", "Operation: try_parse<int>(\"0\")", "Operation: parse<int>(\"a\")", "Operation: try_parse<int>(\"a\")"};
// Time four different implementations for parsing
// an integer from a string.
for (auto operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
auto num_ticks = 0l;
[[maybe_unused]] auto num_rollovers = 0l;
auto max_ticks = 0l;
auto min_ticks = numeric_limits<long>::max();
auto index_fastest = -1;
auto index_slowest = -1;
auto milli_sec = 0l;
auto time_10k_operations = stopwatch::start_new();
// Run the current operation 10001 times.
// The first execution time will be tossed out, since it can skew the average time.
for (auto i = 0; i <= num_iterations; i++) {
auto ticks_this_time = 0l;
auto input_num = 0;
auto time_per_parse = stopwatch {};
switch (operation) {
case 0:
// Parse a valid integer using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("0");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 1:
// Parse a valid integer using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse<int>("0", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 2:
// Parse an invalid value using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("a");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 3:
// Parse an invalid value using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse("a", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
default:
break;
}
// Skip over the time for the first operation, just in case it caused a one-time performance hit.
if (i == 0) {
time_10k_operations.reset();
time_10k_operations.start();
} else {
// Update operation statistics for iterations 1-10000.
if (max_ticks < ticks_this_time) {
index_slowest = i;
max_ticks = ticks_this_time;
}
if (min_ticks > ticks_this_time) {
index_fastest = i;
min_ticks = ticks_this_time;
}
num_ticks += ticks_this_time;
if (num_ticks < ticks_this_time) {
// Keep track of rollovers.
num_rollovers ++;
}
}
}
// Display the statistics for 10000 iterations.
time_10k_operations.stop();
milli_sec = time_10k_operations.elapsed_milliseconds();
console::write_line("{0} Summary:", operation_names[operation]);
console::write_line(" Slowest time: #{0}/{1} = {2} ticks", index_slowest, num_iterations, max_ticks);
console::write_line(" Fastest time: #{0}/{1} = {2} ticks", index_fastest, num_iterations, min_ticks);
console::write_line(" Average time: {0} ticks = {1} nanoseconds", num_ticks / num_iterations, (num_ticks * nanosec_per_tick) / num_iterations);
console::write_line(" Total time looping through {0} operations: {1} milliseconds", num_iterations, milli_sec);
}
}
};
auto main()->int {
operations_timer::display_timer_properties();
console::write_line("Press the Enter key to begin:");
operations_timer::time_operations();
}
// This code can produces the following output :
//
// Operations timed using the system's high-resolution performance counter.
// Timer frequency in ticks per second = 1000000000
// Timer is accurate within 1 nanoseconds
//
// Press the Enter key to begin:
//
//
// Operation: parse<int>("0") Summary:
// Slowest time: #7232/10000 = 505 ticks
// Fastest time: #1278/10000 = 20 ticks
// Average time: 26 ticks = 26 nanoseconds
// Total time looping through 10000 operations: 28 milliseconds
//
// Operation: try_parse<int>("0") Summary:
// Slowest time: #2910/10000 = 312 ticks
// Fastest time: #5105/10000 = 19 ticks
// Average time: 20 ticks = 20 nanoseconds
// Total time looping through 10000 operations: 22 milliseconds
//
// Operation: parse<int>("a") Summary:
// Slowest time: #7001/10000 = 19279 ticks
// Fastest time: #3392/10000 = 4881 ticks
// Average time: 5878 ticks = 5878 nanoseconds
// Total time looping through 10000 operations: 5882 milliseconds
//
// Operation: try_parse<int>("a") Summary:
// Slowest time: #3157/10000 = 14341 ticks
// Fastest time: #20/10000 = 5809 ticks
// Average time: 6532 ticks = 6532 nanoseconds
// Total time looping through 10000 operations: 6536 milliseconds
Examples:
lcd_label2.cpp, stopwatch.cpp, stopwatch_constructor.cpp, and stopwatch_form.cpp.

Constructors

 stopwatch ()=default
 Initializes a new instance of the xtd::diagnostics::stopwatch class. More...
 

Properties

time_span elapsed () const noexcept
 Gets the total elapsed time measured by the current instance. More...
 
int64 elapsed_milliseconds () const noexcept
 Gets the total elapsed time measured by the current instance, in milliseconds. More...
 
int64 elapsed_nanoseconds () const noexcept
 Gets the total elapsed time measured by the current instance, in nanoseconds. More...
 
int64 elapsed_ticks () const noexcept
 Gets the total elapsed time measured by the current instance, in timer ticks. More...
 
bool is_running () const noexcept
 Gets a value indicating whether the stopwatch timer is running. More...
 
static int64 frequency () noexcept
 Gets the frequency of the timer as the number of nanoseconds per second. This field is read-only. More...
 
static bool is_high_resolution () noexcept
 Indicates whether the timer is based on a high-resolution performance counter. This field is read-only. More...
 

Methods

void reset () noexcept
 Stops time interval measurement and resets the elapsed time to zero. More...
 
void restart () noexcept
 stops time interval measurement, resets the elapsed time to zero, and starts measuring elapsed time. More...
 
void start () noexcept
 Starts, or resumes, measuring elapsed time for an interval. More...
 
void stop () noexcept
 Stops measuring elapsed time for an interval. More...
 
static std::chrono::nanoseconds get_timestamp () noexcept
 Gets the current number of nanoseconds in the timer mechanism. More...
 
static int64 get_timestamp_milliseconds () noexcept
 Gets the current number of nanoseconds in the timer mechanism, in milliseconds. More...
 
static int64 get_timestamp_nanoseconds () noexcept
 Gets the current number of nanoseconds in the timer mechanism, in nanoseconds. More...
 
static int64 get_timestamp_ticks () noexcept
 Gets the current number of nanoseconds in the timer mechanism, in ticks. More...
 
static stopwatch start_new () noexcept
 Initializes a new xtd::diagnostics::stopwatch instance, sets the xtd::diagnostics::stopwatch::elapsed time property to zero, and starts measuring elapsed time. More...
 

Additional Inherited Members

- Public Member Functions inherited from xtd::object
 object ()=default
 Create a new instance of the ultimate base class object. More...
 
bool equals (const object &obj) const noexcept
 Determines whether the specified object is equal to the current object. More...
 
virtual size_t get_hash_code () const noexcept
 Serves as a hash function for a particular type. More...
 
virtual type_object get_type () const noexcept
 Gets the type of the current instance. More...
 
template<typename object_t >
std::unique_ptr< object_t > memberwise_clone () const noexcept
 Creates a shallow copy of the current object. More...
 
virtual xtd::ustring to_string () const noexcept
 Returns a sxd::ustring that represents the current object. More...
 
- Static Public Member Functions inherited from xtd::object
static bool equals (const object &object_a, const object &object_b) noexcept
 Determines whether the specified object instances are considered equal. More...
 
static bool reference_equals (const object &object_a, const object &object_b) noexcept
 Determines whether the specified object instances are the same instance. More...
 

Constructor & Destructor Documentation

◆ stopwatch()

xtd::diagnostics::stopwatch::stopwatch ( )
default

Initializes a new instance of the xtd::diagnostics::stopwatch class.

Remarks
The returned xtd::diagnostics::stopwatch instance is stopped, and the xtd::diagnostics::stopwatch::elapsed time property of the instance is zero.
Use the xtd::diagnostics::stopwatch::start method to begin measuring elapsed time with the new xtd::diagnostics::stopwatch instance. Use the xtd::diagnostics::stopwatch::start_new method to initialize a new xtd::diagnostics::stopwatch instance and immediately start it.
Examples
The following example initializes a xtd::diagnostics::stopwatch instance by using a simple class constructor.
#include <xtd/diagnostics/stopwatch>
#include <xtd/threading/thread>
#include <xtd/console>
#include <chrono>
using namespace std::chrono;
using namespace xtd;
using namespace xtd::threading;
auto main()->int {
thread::sleep(10000_ms);
// Get the elapsed time as a duration value.
auto ts = stopwatch.elapsed();
// Format and display the duration value.
auto elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ts, ts.milliseconds() / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

Member Function Documentation

◆ elapsed()

time_span xtd::diagnostics::stopwatch::elapsed ( ) const
noexcept

Gets the total elapsed time measured by the current instance.

Returns
A std::chrono::nanoseconds representing the total elapsed time measured by the current instance.
Remarks
This property represents the number of elapsed nanoseconds in the underlying timer mechanism. A nanosecond is the smallest unit of time that the stopwatch timer can measure. Use the Frequency field to convert the ElapsedTicks value into a number of seconds.
In a typical xtd::diagnostics::stopwatch scenario, you call the xtd::diagnostics::stopwatch::start method, then eventually call the xtd::diagnostics::stopwatch::stop method, and then you check elapsed time using the xtd::diagnostics::stopwatch::elapsed property.
Use the xtd::diagnostics::stopwatch::elapsed property to retrieve the elapsed time value using std::chrono::nanoseconds methods and properties. For example, you can format the returned std::chrono::nanoseconds instance into a text representation, or pass it to another class that requires a std::chrono::duration parameter.
You can query the properties xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_milliseconds, xtd::diagnostics::stopwatch::elapsed_ticks, and xtd::diagnostics::stopwatch::elapsed_nanoseconds while the xtd::diagnostics::stopwatch instance is running or stopped. The elapsed time properties steadily increase while the xtd::diagnostics::stopwatch is running; they remain constant when the instance is stopped.
By default, the elapsed time value of a xtd::diagnostics::stopwatch instance equals the total of all measured time intervals. Each call to start begins counting at the cumulative elapsed time; each call to xtd::diagnostics::stopwatch::stop ends the current interval measurement and freezes the cumulative elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in an existing xtd::diagnostics::stopwatch instance.
Examples
The following example initializes a xtd::diagnostics::stopwatch instance by using a simple class constructor.
#include <xtd/diagnostics/stopwatch>
#include <xtd/threading/thread>
#include <xtd/console>
#include <chrono>
using namespace std::chrono;
using namespace xtd;
using namespace xtd::threading;
auto main()->int {
thread::sleep(10000_ms);
// Get the elapsed time as a duration value.
auto ts = stopwatch.elapsed();
// Format and display the duration value.
auto elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ts, ts.milliseconds() / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

◆ elapsed_milliseconds()

int64 xtd::diagnostics::stopwatch::elapsed_milliseconds ( ) const
noexcept

Gets the total elapsed time measured by the current instance, in milliseconds.

Returns
A long integer representing the total number of milliseconds measured by the current instance.
Remarks
This property represents elapsed time rounded down to the nearest whole millisecond value. For higher precision measurements, use the xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_ticks or xtd::diagnostics::stopwatch::elapsed_nanoseconds properties.
You can query the properties xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_milliseconds, xtd::diagnostics::stopwatch::elapsed_ticks, and xtd::diagnostics::stopwatch::elapsed_nanoseconds while the xtd::diagnostics::stopwatch instance is running or stopped. The elapsed time properties steadily increase while the xtd::diagnostics::stopwatch is running; they remain constant when the instance is stopped.
By default, the elapsed time value of a xtd::diagnostics::stopwatch instance equals the total of all measured time intervals. Each call to start begins counting at the cumulative elapsed time; each call to xtd::diagnostics::stopwatch::stop ends the current interval measurement and freezes the cumulative elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in an existing xtd::diagnostics::stopwatch instance.
Examples
The following example demonstrates how to use the xtd::diagnostics::stopwatch class to determine the execution time for an application.
#include <xtd/diagnostics/stopwatch>
#include <xtd/console>
#include <limits>
using namespace std;
using namespace xtd;
using namespace xtd::diagnostics;
class operations_timer {
public:
static void display_timer_properties() {
// Display the timer frequency and resolution.
console::write_line("Operations timed using the system's high-resolution performance counter.");
else
console::write_line("Operations timed using the standard date time.");
console::write_line(" Timer frequency in ticks per second = {0}", frequency);
auto nanosec_per_tick = (1000l * 1000l * 1000l) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
auto nanosec_per_tick = (1000l * 1000l * 1000l) / stopwatch::frequency();
constexpr auto num_iterations = 10000;
// Define the operation title names.
auto operation_names = vector {"Operation: parse<int>(\"0\")", "Operation: try_parse<int>(\"0\")", "Operation: parse<int>(\"a\")", "Operation: try_parse<int>(\"a\")"};
// Time four different implementations for parsing
// an integer from a string.
for (auto operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
auto num_ticks = 0l;
[[maybe_unused]] auto num_rollovers = 0l;
auto max_ticks = 0l;
auto min_ticks = numeric_limits<long>::max();
auto index_fastest = -1;
auto index_slowest = -1;
auto milli_sec = 0l;
auto time_10k_operations = stopwatch::start_new();
// Run the current operation 10001 times.
// The first execution time will be tossed out, since it can skew the average time.
for (auto i = 0; i <= num_iterations; i++) {
auto ticks_this_time = 0l;
auto input_num = 0;
auto time_per_parse = stopwatch {};
switch (operation) {
case 0:
// Parse a valid integer using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("0");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 1:
// Parse a valid integer using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse<int>("0", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 2:
// Parse an invalid value using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("a");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 3:
// Parse an invalid value using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse("a", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
default:
break;
}
// Skip over the time for the first operation, just in case it caused a one-time performance hit.
if (i == 0) {
time_10k_operations.reset();
time_10k_operations.start();
} else {
// Update operation statistics for iterations 1-10000.
if (max_ticks < ticks_this_time) {
index_slowest = i;
max_ticks = ticks_this_time;
}
if (min_ticks > ticks_this_time) {
index_fastest = i;
min_ticks = ticks_this_time;
}
num_ticks += ticks_this_time;
if (num_ticks < ticks_this_time) {
// Keep track of rollovers.
num_rollovers ++;
}
}
}
// Display the statistics for 10000 iterations.
time_10k_operations.stop();
milli_sec = time_10k_operations.elapsed_milliseconds();
console::write_line("{0} Summary:", operation_names[operation]);
console::write_line(" Slowest time: #{0}/{1} = {2} ticks", index_slowest, num_iterations, max_ticks);
console::write_line(" Fastest time: #{0}/{1} = {2} ticks", index_fastest, num_iterations, min_ticks);
console::write_line(" Average time: {0} ticks = {1} nanoseconds", num_ticks / num_iterations, (num_ticks * nanosec_per_tick) / num_iterations);
console::write_line(" Total time looping through {0} operations: {1} milliseconds", num_iterations, milli_sec);
}
}
};
auto main()->int {
operations_timer::display_timer_properties();
console::write_line("Press the Enter key to begin:");
operations_timer::time_operations();
}
// This code can produces the following output :
//
// Operations timed using the system's high-resolution performance counter.
// Timer frequency in ticks per second = 1000000000
// Timer is accurate within 1 nanoseconds
//
// Press the Enter key to begin:
//
//
// Operation: parse<int>("0") Summary:
// Slowest time: #7232/10000 = 505 ticks
// Fastest time: #1278/10000 = 20 ticks
// Average time: 26 ticks = 26 nanoseconds
// Total time looping through 10000 operations: 28 milliseconds
//
// Operation: try_parse<int>("0") Summary:
// Slowest time: #2910/10000 = 312 ticks
// Fastest time: #5105/10000 = 19 ticks
// Average time: 20 ticks = 20 nanoseconds
// Total time looping through 10000 operations: 22 milliseconds
//
// Operation: parse<int>("a") Summary:
// Slowest time: #7001/10000 = 19279 ticks
// Fastest time: #3392/10000 = 4881 ticks
// Average time: 5878 ticks = 5878 nanoseconds
// Total time looping through 10000 operations: 5882 milliseconds
//
// Operation: try_parse<int>("a") Summary:
// Slowest time: #3157/10000 = 14341 ticks
// Fastest time: #20/10000 = 5809 ticks
// Average time: 6532 ticks = 6532 nanoseconds
// Total time looping through 10000 operations: 6536 milliseconds
Examples:
lcd_label2.cpp.

◆ elapsed_nanoseconds()

int64 xtd::diagnostics::stopwatch::elapsed_nanoseconds ( ) const
noexcept

Gets the total elapsed time measured by the current instance, in nanoseconds.

Returns
A long integer representing the total number of nanoseconds measured by the current instance.
Remarks
This property represents the number of elapsed nanoseconds in the underlying timer mechanism. A nanosecond is the smallest unit of time that the stopwatch timer can measure. Use the Frequency field to convert the ElapsedTicks value into a number of seconds.
You can query the properties xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_milliseconds, xtd::diagnostics::stopwatch::elapsed_ticks, and xtd::diagnostics::stopwatch::elapsed_nanoseconds while the xtd::diagnostics::stopwatch instance is running or stopped. The elapsed time properties steadily increase while the xtd::diagnostics::stopwatch is running; they remain constant when the instance is stopped.
By default, the elapsed time value of a xtd::diagnostics::stopwatch instance equals the total of all measured time intervals. Each call to start begins counting at the cumulative elapsed time; each call to xtd::diagnostics::stopwatch::stop ends the current interval measurement and freezes the cumulative elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in an existing xtd::diagnostics::stopwatch instance.

◆ elapsed_ticks()

int64 xtd::diagnostics::stopwatch::elapsed_ticks ( ) const
noexcept

Gets the total elapsed time measured by the current instance, in timer ticks.

Returns
A long integer representing the total number of timer ticks measured by the current instance.
Remarks
This property represents elapsed time rounded down to the nearest whole nanoseconds value. For higher precision measurements, use the xtd::diagnostics::stopwatch::elapsed_nanoseconds property.
You can query the properties xtd::diagnostics::stopwatch::elapsed, xtd::diagnostics::stopwatch::elapsed_milliseconds, xtd::diagnostics::stopwatch::elapsed_ticks, and xtd::diagnostics::stopwatch::elapsed_nanoseconds while the xtd::diagnostics::stopwatch instance is running or stopped. The elapsed time properties steadily increase while the xtd::diagnostics::stopwatch is running; they remain constant when the instance is stopped.
By default, the elapsed time value of a xtd::diagnostics::stopwatch instance equals the total of all measured time intervals. Each call to start begins counting at the cumulative elapsed time; each call to xtd::diagnostics::stopwatch::stop ends the current interval measurement and freezes the cumulative elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in an existing xtd::diagnostics::stopwatch instance.
Examples
The following example demonstrates how to use the xtd::diagnostics::stopwatch class to determine the execution time for an application.
#include <xtd/diagnostics/stopwatch>
#include <xtd/console>
#include <limits>
using namespace std;
using namespace xtd;
using namespace xtd::diagnostics;
class operations_timer {
public:
static void display_timer_properties() {
// Display the timer frequency and resolution.
console::write_line("Operations timed using the system's high-resolution performance counter.");
else
console::write_line("Operations timed using the standard date time.");
console::write_line(" Timer frequency in ticks per second = {0}", frequency);
auto nanosec_per_tick = (1000l * 1000l * 1000l) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
auto nanosec_per_tick = (1000l * 1000l * 1000l) / stopwatch::frequency();
constexpr auto num_iterations = 10000;
// Define the operation title names.
auto operation_names = vector {"Operation: parse<int>(\"0\")", "Operation: try_parse<int>(\"0\")", "Operation: parse<int>(\"a\")", "Operation: try_parse<int>(\"a\")"};
// Time four different implementations for parsing
// an integer from a string.
for (auto operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
auto num_ticks = 0l;
[[maybe_unused]] auto num_rollovers = 0l;
auto max_ticks = 0l;
auto min_ticks = numeric_limits<long>::max();
auto index_fastest = -1;
auto index_slowest = -1;
auto milli_sec = 0l;
auto time_10k_operations = stopwatch::start_new();
// Run the current operation 10001 times.
// The first execution time will be tossed out, since it can skew the average time.
for (auto i = 0; i <= num_iterations; i++) {
auto ticks_this_time = 0l;
auto input_num = 0;
auto time_per_parse = stopwatch {};
switch (operation) {
case 0:
// Parse a valid integer using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("0");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 1:
// Parse a valid integer using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse<int>("0", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 2:
// Parse an invalid value using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("a");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 3:
// Parse an invalid value using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse("a", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
default:
break;
}
// Skip over the time for the first operation, just in case it caused a one-time performance hit.
if (i == 0) {
time_10k_operations.reset();
time_10k_operations.start();
} else {
// Update operation statistics for iterations 1-10000.
if (max_ticks < ticks_this_time) {
index_slowest = i;
max_ticks = ticks_this_time;
}
if (min_ticks > ticks_this_time) {
index_fastest = i;
min_ticks = ticks_this_time;
}
num_ticks += ticks_this_time;
if (num_ticks < ticks_this_time) {
// Keep track of rollovers.
num_rollovers ++;
}
}
}
// Display the statistics for 10000 iterations.
time_10k_operations.stop();
milli_sec = time_10k_operations.elapsed_milliseconds();
console::write_line("{0} Summary:", operation_names[operation]);
console::write_line(" Slowest time: #{0}/{1} = {2} ticks", index_slowest, num_iterations, max_ticks);
console::write_line(" Fastest time: #{0}/{1} = {2} ticks", index_fastest, num_iterations, min_ticks);
console::write_line(" Average time: {0} ticks = {1} nanoseconds", num_ticks / num_iterations, (num_ticks * nanosec_per_tick) / num_iterations);
console::write_line(" Total time looping through {0} operations: {1} milliseconds", num_iterations, milli_sec);
}
}
};
auto main()->int {
operations_timer::display_timer_properties();
console::write_line("Press the Enter key to begin:");
operations_timer::time_operations();
}
// This code can produces the following output :
//
// Operations timed using the system's high-resolution performance counter.
// Timer frequency in ticks per second = 1000000000
// Timer is accurate within 1 nanoseconds
//
// Press the Enter key to begin:
//
//
// Operation: parse<int>("0") Summary:
// Slowest time: #7232/10000 = 505 ticks
// Fastest time: #1278/10000 = 20 ticks
// Average time: 26 ticks = 26 nanoseconds
// Total time looping through 10000 operations: 28 milliseconds
//
// Operation: try_parse<int>("0") Summary:
// Slowest time: #2910/10000 = 312 ticks
// Fastest time: #5105/10000 = 19 ticks
// Average time: 20 ticks = 20 nanoseconds
// Total time looping through 10000 operations: 22 milliseconds
//
// Operation: parse<int>("a") Summary:
// Slowest time: #7001/10000 = 19279 ticks
// Fastest time: #3392/10000 = 4881 ticks
// Average time: 5878 ticks = 5878 nanoseconds
// Total time looping through 10000 operations: 5882 milliseconds
//
// Operation: try_parse<int>("a") Summary:
// Slowest time: #3157/10000 = 14341 ticks
// Fastest time: #20/10000 = 5809 ticks
// Average time: 6532 ticks = 6532 nanoseconds
// Total time looping through 10000 operations: 6536 milliseconds

◆ frequency()

static int64 xtd::diagnostics::stopwatch::frequency ( )
staticnoexcept

Gets the frequency of the timer as the number of nanoseconds per second. This field is read-only.

Returns
The frequency of the timer as the number of nanoseconds per second.

◆ get_timestamp()

static std::chrono::nanoseconds xtd::diagnostics::stopwatch::get_timestamp ( )
staticnoexcept

Gets the current number of nanoseconds in the timer mechanism.

Returns
A std::chrono::nanoseconds representing the nanosecond counter value of the underlying timer mechanism.

◆ get_timestamp_milliseconds()

static int64 xtd::diagnostics::stopwatch::get_timestamp_milliseconds ( )
staticnoexcept

Gets the current number of nanoseconds in the timer mechanism, in milliseconds.

Returns
A long integer representing the millisecond counter value of the underlying timer mechanism.

◆ get_timestamp_nanoseconds()

static int64 xtd::diagnostics::stopwatch::get_timestamp_nanoseconds ( )
staticnoexcept

Gets the current number of nanoseconds in the timer mechanism, in nanoseconds.

Returns
A long integer representing the nanosecond counter value of the underlying timer mechanism.

◆ get_timestamp_ticks()

static int64 xtd::diagnostics::stopwatch::get_timestamp_ticks ( )
staticnoexcept

Gets the current number of nanoseconds in the timer mechanism, in ticks.

Returns
A long integer representing the ticks counter value of the underlying timer mechanism.

◆ is_high_resolution()

static bool xtd::diagnostics::stopwatch::is_high_resolution ( )
staticnoexcept

Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.

Returns
true if the timer is based on a high-resolution performance count; otherwise, false.
Remarks
The timer used by the xtd::diagnostics::stopwatch class depends on the system hardware and operating system. xtd::diagnostics::stopwatch::is_high_resolution is true if the xtd::diagnostics::stopwatch timer is based on a high-resolution performance counter. Otherwise, xtd::diagnostics::stopwatch::is_high_resolution is false, which indicates that the xtd::diagnostics::stopwatch timer is based on the system timer.
Returns always true

◆ is_running()

bool xtd::diagnostics::stopwatch::is_running ( ) const
noexcept

Gets a value indicating whether the stopwatch timer is running.

Returns
true if the xtd::diagnostics::stopwatch instance is currently running and measuring elapsed time for an interval; otherwise, false.
Remarks
A xtd::diagnostics::stopwatch instance begins running with a call to xtd::diagnostics::stopwatch::start or xtd::diagnostics::stopwatch::start_new. The instance stops running with a call to xtd::diagnostics::stopwatch::stop or xtd::diagnostics::stopwatch::reset.

◆ reset()

void xtd::diagnostics::stopwatch::reset ( )
noexcept

Stops time interval measurement and resets the elapsed time to zero.

Remarks
A xtd::diagnostics::stopwatch instance calculates and retains the cumulative elapsed time across multiple time intervals, until the instance is reset. Use xtd::diagnostics::stopwatch::stop to stop the current interval measurement and retain the cumulative elapsed time value. Use xtd::diagnostics::stopwatch::reset to stop any interval measurement in progress and clear the elapsed time value.
Examples:
lcd_label2.cpp.

◆ restart()

void xtd::diagnostics::stopwatch::restart ( )
noexcept

stops time interval measurement, resets the elapsed time to zero, and starts measuring elapsed time.

Remarks
A xtd::diagnostics::stopwatch instance calculates and retains the cumulative elapsed time across multiple time intervals, until the instance is reset or restarted. Use xtd::diagnostics::stopwatch::stop to stop the current interval measurement and retain the cumulative elapsed time value. Use xtd::diagnostics::stopwatch::reset to stop any interval measurement in progress and clear the elapsed time value. Use xtd::diagnostics::stopwatch::restart to stop current interval measurement and start a new interval measurement.
Examples:
lcd_label2.cpp.

◆ start()

void xtd::diagnostics::stopwatch::start ( )
noexcept

Starts, or resumes, measuring elapsed time for an interval.

Remarks
In a typical xtd::diagnostics::stopwatch scenario, you call the xtd::diagnostics::stopwatch::start method, then eventually call the xtd::diagnostics::stopwatch::stop method, and then you check elapsed time using the xtd::diagnostics::stopwatch::elapsed property.
Once started, a xtd::diagnostics::stopwatch timer measures the current interval, in elapsed timer ticks, until the instance is stopped or reset. starting a xtd::diagnostics::stopwatch that is already running does not change the timer state or reset the elapsed time properties.
When a stopwatch instance measures more than one interval, the start method resumes measuring time from the current elapsed time value. A stopwatch instance calculates and retains the cumulative elapsed time across multiple time intervals, until the instance is reset. Use the reset method before calling start to clear the cumulative elapsed time in a stopwatch instance. Use the restart method to reset and start the stopwatch with a single command.
Examples
The following example initializes a xtd::diagnostics::stopwatch instance by using a simple class constructor.
#include <xtd/diagnostics/stopwatch>
#include <xtd/threading/thread>
#include <xtd/console>
#include <chrono>
using namespace std::chrono;
using namespace xtd;
using namespace xtd::threading;
auto main()->int {
thread::sleep(10000_ms);
// Get the elapsed time as a duration value.
auto ts = stopwatch.elapsed();
// Format and display the duration value.
auto elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ts, ts.milliseconds() / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00
Examples:
lcd_label2.cpp, and stopwatch_constructor.cpp.

◆ start_new()

static stopwatch xtd::diagnostics::stopwatch::start_new ( )
staticnoexcept

Initializes a new xtd::diagnostics::stopwatch instance, sets the xtd::diagnostics::stopwatch::elapsed time property to zero, and starts measuring elapsed time.

Remarks
This method is equivalent to calling the xtd::diagnostics::stopwatch constructor and then calling xtd::diagnostics::stopwatch::start on the new instance.
Examples
The following example demonstrates how to use the xtd::diagnostics::stopwatch class to determine the execution time for an application.
#include <xtd/diagnostics/stopwatch>
#include <xtd/console>
#include <limits>
using namespace std;
using namespace xtd;
using namespace xtd::diagnostics;
class operations_timer {
public:
static void display_timer_properties() {
// Display the timer frequency and resolution.
console::write_line("Operations timed using the system's high-resolution performance counter.");
else
console::write_line("Operations timed using the standard date time.");
console::write_line(" Timer frequency in ticks per second = {0}", frequency);
auto nanosec_per_tick = (1000l * 1000l * 1000l) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
auto nanosec_per_tick = (1000l * 1000l * 1000l) / stopwatch::frequency();
constexpr auto num_iterations = 10000;
// Define the operation title names.
auto operation_names = vector {"Operation: parse<int>(\"0\")", "Operation: try_parse<int>(\"0\")", "Operation: parse<int>(\"a\")", "Operation: try_parse<int>(\"a\")"};
// Time four different implementations for parsing
// an integer from a string.
for (auto operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
auto num_ticks = 0l;
[[maybe_unused]] auto num_rollovers = 0l;
auto max_ticks = 0l;
auto min_ticks = numeric_limits<long>::max();
auto index_fastest = -1;
auto index_slowest = -1;
auto milli_sec = 0l;
auto time_10k_operations = stopwatch::start_new();
// Run the current operation 10001 times.
// The first execution time will be tossed out, since it can skew the average time.
for (auto i = 0; i <= num_iterations; i++) {
auto ticks_this_time = 0l;
auto input_num = 0;
auto time_per_parse = stopwatch {};
switch (operation) {
case 0:
// Parse a valid integer using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("0");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 1:
// Parse a valid integer using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse<int>("0", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 2:
// Parse an invalid value using a try-catch statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
try {
input_num = parse<int>("a");
} catch (const system_exception&) {
input_num = 0;
}
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
case 3:
// Parse an invalid value using the try_parse statement.
// Start a new stopwatch timer.
time_per_parse = stopwatch::start_new();
if (!try_parse("a", input_num))
input_num = 0;
// Stop the timer, and save the elapsed ticks for the operation.
time_per_parse.stop();
ticks_this_time = time_per_parse.elapsed_ticks();
break;
default:
break;
}
// Skip over the time for the first operation, just in case it caused a one-time performance hit.
if (i == 0) {
time_10k_operations.reset();
time_10k_operations.start();
} else {
// Update operation statistics for iterations 1-10000.
if (max_ticks < ticks_this_time) {
index_slowest = i;
max_ticks = ticks_this_time;
}
if (min_ticks > ticks_this_time) {
index_fastest = i;
min_ticks = ticks_this_time;
}
num_ticks += ticks_this_time;
if (num_ticks < ticks_this_time) {
// Keep track of rollovers.
num_rollovers ++;
}
}
}
// Display the statistics for 10000 iterations.
time_10k_operations.stop();
milli_sec = time_10k_operations.elapsed_milliseconds();
console::write_line("{0} Summary:", operation_names[operation]);
console::write_line(" Slowest time: #{0}/{1} = {2} ticks", index_slowest, num_iterations, max_ticks);
console::write_line(" Fastest time: #{0}/{1} = {2} ticks", index_fastest, num_iterations, min_ticks);
console::write_line(" Average time: {0} ticks = {1} nanoseconds", num_ticks / num_iterations, (num_ticks * nanosec_per_tick) / num_iterations);
console::write_line(" Total time looping through {0} operations: {1} milliseconds", num_iterations, milli_sec);
}
}
};
auto main()->int {
operations_timer::display_timer_properties();
console::write_line("Press the Enter key to begin:");
operations_timer::time_operations();
}
// This code can produces the following output :
//
// Operations timed using the system's high-resolution performance counter.
// Timer frequency in ticks per second = 1000000000
// Timer is accurate within 1 nanoseconds
//
// Press the Enter key to begin:
//
//
// Operation: parse<int>("0") Summary:
// Slowest time: #7232/10000 = 505 ticks
// Fastest time: #1278/10000 = 20 ticks
// Average time: 26 ticks = 26 nanoseconds
// Total time looping through 10000 operations: 28 milliseconds
//
// Operation: try_parse<int>("0") Summary:
// Slowest time: #2910/10000 = 312 ticks
// Fastest time: #5105/10000 = 19 ticks
// Average time: 20 ticks = 20 nanoseconds
// Total time looping through 10000 operations: 22 milliseconds
//
// Operation: parse<int>("a") Summary:
// Slowest time: #7001/10000 = 19279 ticks
// Fastest time: #3392/10000 = 4881 ticks
// Average time: 5878 ticks = 5878 nanoseconds
// Total time looping through 10000 operations: 5882 milliseconds
//
// Operation: try_parse<int>("a") Summary:
// Slowest time: #3157/10000 = 14341 ticks
// Fastest time: #20/10000 = 5809 ticks
// Average time: 6532 ticks = 6532 nanoseconds
// Total time looping through 10000 operations: 6536 milliseconds

◆ stop()

void xtd::diagnostics::stopwatch::stop ( )
noexcept

Stops measuring elapsed time for an interval.

Remarks
In a typical xtd::diagnostics::stopwatch scenario, you call the xtd::diagnostics::stopwatch::start method, then eventually call the xtd::diagnostics::stopwatch::stop method, and then you check elapsed time using the xtd::diagnostics::stopwatch::elapsed property.
The xtd::diagnostics::stopwatch::stop method ends the current time interval measurement. stopping a xtd::diagnostics::stopwatch that is not running does not change the timer state or reset the elapsed time properties.
When a xtd::diagnostics::stopwatch instance measures more than one interval, the xtd::diagnostics::stopwatch::stop method is equivalent to pausing the elapsed time measurement. A subsequent call to xtd::diagnostics::stopwatch::start resumes measuring time from the current elapsed time value. Use the xtd::diagnostics::stopwatch::reset method to clear the cumulative elapsed time in a xtd::diagnostics::stopwatch instance.
Examples
The following example initializes a xtd::diagnostics::stopwatch instance by using a simple class constructor.
#include <xtd/diagnostics/stopwatch>
#include <xtd/threading/thread>
#include <xtd/console>
#include <chrono>
using namespace std::chrono;
using namespace xtd;
using namespace xtd::threading;
auto main()->int {
thread::sleep(10000_ms);
// Get the elapsed time as a duration value.
auto ts = stopwatch.elapsed();
// Format and display the duration value.
auto elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ts, ts.milliseconds() / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00
Examples:
lcd_label2.cpp.

The documentation for this class was generated from the following file: