179 lines
6.6 KiB
C#
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);
|
|
}
|
|
}
|
|
} |