Files
CSClasses/CSClasses/Stopwatch.cs

179 lines
6.6 KiB
C#

//C#/CSClasses/Stopwatch.cs
//Matthew Ellison
// Created: 08-21-20
//Modified: 08-21-20
//This file contains a class that is used to time the execution time of other programs
/*
Copyright (C) 2020 Matthew Ellison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace mee{
public class Stopwatch{
//Variables
private readonly System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); //The stopwatch that is used
private enum TIME_RESOLUTION{ NANOSECOND, MICROSECOND, MILLISECOND, SECOND, MINUTE, HOUR, ERROR };
private const int NUM_TO_RUN = 100000;
private readonly long nanosecPerTick = 1000000000L / System.Diagnostics.Stopwatch.Frequency;
//Functions
//Constructor makes sure all values are set to defaults
public Stopwatch(){
}
//Simultates starting a stopwatch
public void Start(){
stopwatch.Start();
}
//Simulates stopping a stopwatch
public void Stop(){
stopwatch.Stop();
}
//Resets all the variables in teh stopwatch
public void Reset(){
stopwatch.Reset();
}
//Returns the timer in nanoseconds
public decimal GetNano(){
return (decimal)nanosecPerTick * (decimal)stopwatch.ElapsedTicks;
}
//Returns the timer in microseconds
public decimal GetMicro(){
return GetNano() / 1000m;
}
//Returns the timer in milliseconds
public decimal GetMilli(){
return GetNano() / 1000000m;
}
//Returns the timer in seconds
public decimal GetSecond(){
return GetNano() / 1000000000m;
}
//Returns the timer in minutes
public decimal GetMinute(){
return GetNano() / 60000000000m;
}
//Returns the timer in hours
public decimal GetHour(){
return GetNano() / 3600000000000m;
}
//Returns the timer as a string at the 'best' resolution. (Goal is xxx.xxx)
public string GetStr(){
//Get the current duration from time
return GetStr(GetNano());
}
//Returns a string of the decimal value passed in (assuming the value in nanoseconds)
public static string GetStr(decimal nanoseconds){
decimal duration = nanoseconds;
//Reduce the number to the appropriate number of digits. (xxx.x)
//This loop works down to seconds
TIME_RESOLUTION resolution;
for(resolution = TIME_RESOLUTION.NANOSECOND;(resolution < TIME_RESOLUTION.SECOND) && (duration >= 1000);++resolution){
duration /= 1000;
}
//Check if the duration needs reduced to minutes
if((duration >= 120) && (resolution == TIME_RESOLUTION.SECOND)){
//Reduce to mintues
duration /= 60;
++resolution;
//Check if the duration needs reduced to hours
if(duration >= 60){
//Reduce to hours
duration /= 60;
++resolution;
}
}
//Turn the number into a string
string time = duration.ToString("C3").Substring(1);
//Tack on the appropriate suffix for resolution
switch(resolution){
case TIME_RESOLUTION.NANOSECOND: time += " nanoseconds"; break;
case TIME_RESOLUTION.MICROSECOND: time += " microseconds"; break;
case TIME_RESOLUTION.MILLISECOND: time += " milliseconds"; break;
case TIME_RESOLUTION.SECOND: time += " seconds"; break;
case TIME_RESOLUTION.MINUTE: time += " minutes"; break;
case TIME_RESOLUTION.HOUR: time += " hours"; break;
case TIME_RESOLUTION.ERROR:
default: time = "There was an error computing the time"; break; //TODO: This should throw an exception instead
}
//Return the string
return time;
}
//Overrides default tostring. returns getStr
public override string ToString(){
return GetStr();
}
//Tests
public static void Main(){
System.Console.WriteLine("Testing start/stop");
TestStartStop();
System.Console.WriteLine("start/stop completed successfully");
System.Console.WriteLine("Testing conversion");
TestConversion();
System.Console.WriteLine("conversion test completed successfully");
System.Console.WriteLine("Testing stringConversion");
TestStringConversion();
System.Console.WriteLine("stringConversion completed successfully");
}
public static void TestStartStop(){
Stopwatch timer = new Stopwatch();
timer.Start();
timer.Stop();
//If it gets here without throwing an exception everything went well
}
public static void TestConversion(){
Stopwatch timer = new Stopwatch();
int sum = 0;
//Start the timer
timer.Start();
//Do something to run some time
for(int cnt = 0;cnt < NUM_TO_RUN;++cnt){
sum += cnt;
}
//Stop the timer
timer.Stop();
//Assert something so the sum isn't ignored during compile
System.Diagnostics.Debug.Assert(sum != 0);
//Check that the different resolutions work out correctly
decimal nano = timer.GetNano();
System.Diagnostics.Debug.Assert(timer.GetMicro() == (nano / 1000m), "Micro resolution test failed");
System.Diagnostics.Debug.Assert(timer.GetMilli() == (nano / 1000000m), "Milli resolution test failed");
System.Diagnostics.Debug.Assert(timer.GetSecond() == (nano / 1000000000m), "Second resolution test failed");
System.Diagnostics.Debug.Assert(timer.GetMinute() == (nano / 60000000000m), "Minute resolution test failed");
System.Diagnostics.Debug.Assert(timer.GetHour() == (nano / 3600000000000m), "Hour resolution test failed");
}
public static void TestStringConversion(){
//Test nanoseconds
string results = Stopwatch.GetStr(1.0m);
System.Diagnostics.Debug.Assert(results == "1.000 nanoseconds", "Failed nanoseconds: " + results);
//Test microseconds
results = Stopwatch.GetStr(1.0e3m);
System.Diagnostics.Debug.Assert(results == "1.00 microsesconds", "Failed microseconds: " + results);
//Test milliseconds
results = Stopwatch.GetStr(1.0e6m);
System.Diagnostics.Debug.Assert(results == "1.00 milliseconds", "Failed milliseconds: " + results);
//Test seconds
results = Stopwatch.GetStr(1.0e9m);
System.Diagnostics.Debug.Assert(results == "1.00 seconds", "Failed seconds: " + results);
//Test minutes
results = Stopwatch.GetStr(1.0e12m);
System.Diagnostics.Debug.Assert(results == "1.00 minutes", "Failed minutes: " + results);
//Test hours
results = Stopwatch.GetStr(1.0e13m);
System.Diagnostics.Debug.Assert(results == "1.00 hours", "Failed hours: " + results);
}
}
}