xtd - Reference Guide  0.1.0
Modern c++17/20 framework to create console, GUI and unit test applications on Windows, macOS, Linux, iOS and android.
Public Member Functions | Static Public Member Functions | List of all members
xtd::diagnostics::stopwatch Class Reference

#include <stopwatch.h>

Definition

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

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/xtd>
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);
long nanosec_per_tick = (1000L*1000L*1000L) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
long nanosec_per_tick = (1000L*1000L*1000L) / stopwatch::frequency();
const long num_iterations = 10000;
// Define the operation title names.
vector operation_names = {"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 (int operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
long num_ticks = 0;
long num_rollovers = 0;
long max_ticks = 0;
long min_ticks = numeric_limits<long>::max();
int index_fastest = -1;
int index_slowest = -1;
long milli_sec = 0;
stopwatch 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 (int i = 0; i <= num_iterations; i++) {
long ticks_this_time = 0;
int input_num;
stopwatch time_per_parse;
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);
}
}
};
int main() {
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

Public Member Functions

 stopwatch ()=default
 Initializes a new instance of the xtd::diagnostics::stopwatch class. More...
 
std::chrono::nanoseconds elapsed () const
 Gets the total elapsed time measured by the current instance. More...
 
int64_t elapsed_milliseconds () const
 Gets the total elapsed time measured by the current instance, in milliseconds. More...
 
int64_t elapsed_nanoseconds () const
 Gets the total elapsed time measured by the current instance, in nanoseconds. More...
 
int64_t elapsed_ticks () const
 Gets the total elapsed time measured by the current instance, in timer ticks. More...
 
bool is_running () const
 Gets a value indicating whether the stopwatch timer is running. More...
 
void reset ()
 Stops time interval measurement and resets the elapsed time to zero. More...
 
void restart ()
 stops time interval measurement, resets the elapsed time to zero, and starts measuring elapsed time. More...
 
void start ()
 Starts, or resumes, measuring elapsed time for an interval. More...
 
void stop ()
 Stops measuring elapsed time for an interval. More...
 
- Public Member Functions inherited from xtd::object
 object ()=default
 Create a new instance of the ultimate base class object. More...
 
virtual 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...
 
template<typename object_t >
std::unique_ptr< object_t > memberwise_clone () const
 Gets the type of the current instance. More...
 
virtual xtd::ustring to_string () const noexcept
 Returns a std::string that represents the current object. More...
 

Static Public Member Functions

static int64_t frequency ()
 Gets the frequency of the timer as the number of nanoseconds per second. This field is read-only. More...
 
static int64_t get_timestamp ()
 Gets the current number of nanoseconds in the timer mechanism. More...
 
static bool is_high_resolution ()
 Indicates whether the timer is based on a high-resolution performance counter. This field is read-only. More...
 
static stopwatch start_new ()
 Initializes a new xtd::diagnostics::stopwatch instance, sets the xtd::diagnostics::stopwatch::elapsed time property to zero, and starts measuring elapsed time. 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/xtd>
using namespace std::chrono;
using namespace std::literals;
using namespace std::this_thread;
using namespace xtd;
using namespace xtd::diagnostics;
int main() {
stopwatch.start();
sleep_for(10000ms);
stopwatch.stop();
// Get the elapsed time as a duration value.
nanoseconds ns = stopwatch.elapsed();
// Format and display the duration value.
ustring elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ns, duration_cast<milliseconds>(ns).count() % 1000 / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

Member Function Documentation

◆ elapsed()

std::chrono::nanoseconds xtd::diagnostics::stopwatch::elapsed ( ) const

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/xtd>
using namespace std::chrono;
using namespace std::literals;
using namespace std::this_thread;
using namespace xtd;
using namespace xtd::diagnostics;
int main() {
stopwatch stopwatch;
stopwatch.start();
sleep_for(10000ms);
stopwatch.stop();
// Get the elapsed time as a duration value.
nanoseconds ns = stopwatch.elapsed();
// Format and display the duration value.
ustring elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ns, duration_cast<milliseconds>(ns).count() % 1000 / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

◆ elapsed_milliseconds()

int64_t xtd::diagnostics::stopwatch::elapsed_milliseconds ( ) const

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/xtd>
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);
long nanosec_per_tick = (1000L*1000L*1000L) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
long nanosec_per_tick = (1000L*1000L*1000L) / stopwatch::frequency();
const long num_iterations = 10000;
// Define the operation title names.
vector operation_names = {"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 (int operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
long num_ticks = 0;
long num_rollovers = 0;
long max_ticks = 0;
long min_ticks = numeric_limits<long>::max();
int index_fastest = -1;
int index_slowest = -1;
long milli_sec = 0;
stopwatch 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 (int i = 0; i <= num_iterations; i++) {
long ticks_this_time = 0;
int input_num;
stopwatch time_per_parse;
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);
}
}
};
int main() {
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

◆ elapsed_nanoseconds()

int64_t xtd::diagnostics::stopwatch::elapsed_nanoseconds ( ) const

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_t xtd::diagnostics::stopwatch::elapsed_ticks ( ) const

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/xtd>
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);
long nanosec_per_tick = (1000L*1000L*1000L) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
long nanosec_per_tick = (1000L*1000L*1000L) / stopwatch::frequency();
const long num_iterations = 10000;
// Define the operation title names.
vector operation_names = {"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 (int operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
long num_ticks = 0;
long num_rollovers = 0;
long max_ticks = 0;
long min_ticks = numeric_limits<long>::max();
int index_fastest = -1;
int index_slowest = -1;
long milli_sec = 0;
stopwatch 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 (int i = 0; i <= num_iterations; i++) {
long ticks_this_time = 0;
int input_num;
stopwatch time_per_parse;
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);
}
}
};
int main() {
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_t xtd::diagnostics::stopwatch::frequency ( )
static

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 int64_t xtd::diagnostics::stopwatch::get_timestamp ( )
static

Gets the current number of nanoseconds in the timer mechanism.

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

◆ is_high_resolution()

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

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 counte; 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 thextd::diagnostics::stopwatch timer is based on the system timer.
Returns always true

◆ is_running()

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

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 ( )

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.

◆ restart()

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

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.

◆ start()

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

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/xtd>
using namespace std::chrono;
using namespace std::literals;
using namespace std::this_thread;
using namespace xtd;
using namespace xtd::diagnostics;
int main() {
stopwatch stopwatch;
stopwatch.start();
sleep_for(10000ms);
stopwatch.stop();
// Get the elapsed time as a duration value.
nanoseconds ns = stopwatch.elapsed();
// Format and display the duration value.
ustring elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ns, duration_cast<milliseconds>(ns).count() % 1000 / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

◆ start_new()

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

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/xtd>
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);
long nanosec_per_tick = (1000L*1000L*1000L) / frequency;
console::write_line(" Timer is accurate within {0} nanoseconds", nanosec_per_tick);
}
static void time_operations() {
long nanosec_per_tick = (1000L*1000L*1000L) / stopwatch::frequency();
const long num_iterations = 10000;
// Define the operation title names.
vector operation_names = {"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 (int operation = 0; operation <= 3; operation++) {
// Define variables for operation statistics.
long num_ticks = 0;
long num_rollovers = 0;
long max_ticks = 0;
long min_ticks = numeric_limits<long>::max();
int index_fastest = -1;
int index_slowest = -1;
long milli_sec = 0;
stopwatch 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 (int i = 0; i <= num_iterations; i++) {
long ticks_this_time = 0;
int input_num;
stopwatch time_per_parse;
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);
}
}
};
int main() {
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 ( )

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/xtd>
using namespace std::chrono;
using namespace std::literals;
using namespace std::this_thread;
using namespace xtd;
using namespace xtd::diagnostics;
int main() {
stopwatch stopwatch;
stopwatch.start();
sleep_for(10000ms);
stopwatch.stop();
// Get the elapsed time as a duration value.
nanoseconds ns = stopwatch.elapsed();
// Format and display the duration value.
ustring elapsed_time = ustring::format("{0:H}:{0:M}:{0:S}.{1:D2}", ns, duration_cast<milliseconds>(ns).count() % 1000 / 10);
console::write_line("RunTime " + elapsed_time);
}
// This code produces the following output :
//
// RunTime 00:00:10.00

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