#include <xtd/collections/generic/list>
#include <xtd/diagnostics/stopwatch>
#include <xtd/console>
#include <limits>
 
 
class operations_timer {
public:
  static void display_timer_properties() {
    
    if (stopwatch::is_high_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.");
      
    auto frequency = stopwatch::frequency();
    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;
    
    
    auto operation_names = 
list {
"Operation: parse<int>(\"0\")", 
"Operation: try_parse<int>(\"0\")", 
"Operation: parse<int>(\"a\")", 
"Operation: try_parse<int>(\"a\")"};
 
    
    
    
    
    for (auto operation = 0; operation <= 3; operation++) {
      
      auto num_ticks = 0l;
      [[maybe_unused]] auto num_rollovers = 0l;
      auto max_ticks = 0l;
      auto min_ticks = std::numeric_limits<long>::max();
      auto index_fastest = -1;
      auto index_slowest = -1;
      auto milli_sec = 0l;
      
      auto time_10k_operations = stopwatch::start_new();
      
      
      
      
      for (auto i = 0; i <= num_iterations; i++) {
        auto ticks_this_time = 0l;
        auto input_num = 0;
        
        switch (operation) {
          case 0:
            
            
            
            time_per_parse = stopwatch::start_new();
            
            try {
              input_num = parse<int>("0");
              input_num = 0;
            }
            
            
            time_per_parse.stop();
            ticks_this_time = time_per_parse.elapsed_ticks();
            break;
            
          case 1:
            
            
            
            time_per_parse = stopwatch::start_new();
            
            if (!try_parse<int>("0", input_num))
              input_num = 0;
              
            
            time_per_parse.stop();
            ticks_this_time = time_per_parse.elapsed_ticks();
            break;
            
          case 2:
            
            
            
            time_per_parse = stopwatch::start_new();
            
            try {
              input_num = parse<int>("a");
              input_num = 0;
            }
            
            
            time_per_parse.stop();
            ticks_this_time = time_per_parse.elapsed_ticks();
            break;
            
          case 3:
            
            
            
            time_per_parse = stopwatch::start_new();
            
            if (!try_parse("a", input_num))
              input_num = 0;
              
            
            time_per_parse.stop();
            ticks_this_time = time_per_parse.elapsed_ticks();
            break;
            
          default:
            break;
        }
        
        
        if (i == 0) {
          time_10k_operations.reset();
          time_10k_operations.start();
        } else  {
        
          
          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) {
            
            num_rollovers ++;
          }
        }
      }
      
      
      
      time_10k_operations.stop();
      milli_sec = time_10k_operations.elapsed_milliseconds();
      
      console::write_line();
      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();
  console::write_line("Press the Enter key to begin:");
  console::read_line();
  console::write_line();
  
  operations_timer::time_operations();
}
 
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition list.hpp:71
 
Provides a set of methods and properties that you can use to accurately measure elapsed time.
Definition stopwatch.hpp:36
 
The exception that is thrown when a method call is invalid for the object's current state.
Definition system_exception.hpp:18
 
The xtd::collections::generic namespace contains interfaces and classes that define generic collectio...
Definition comparer.hpp:15
 
The xtd::diagnostics namespace provides classes that allow you to interact with system processes,...
Definition assert_dialog_result.hpp:10
 
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10