//typescriptClasses/Stopwatch.ts //Matthew Ellison // Created: 10-18-20 //Modified: 10-18-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 . */ import {InvalidResult} from "./InvalidResult"; import {performance} from "perf_hooks"; //An enum that helps keep track of how many times the time has been reduced in the getStr function enum TIME_RESOLUTION{ NANOSECOND, MICROSECOND, MILLISECOND, SECOND, MINUTE, HOUR, ERROR }; export class Stopwatch{ private startTime: number; private stopTime: number; //Constructor makes sure all values are set to defaults public constructor(){ //Make sure both values are null so it is easier to detect incorrect function calling order this.startTime = null; this.stopTime = null; } //Returns a long with the elapsed time in milliseconds. Used by other functions to get the time before converting it to the correct resolution private getTime(): number{ if(this.startTime == null){ return 0; } else if(this.stopTime == null){ return performance.now() - this.startTime; } else{ return this.stopTime - this.startTime; } } //Simultates starting a stopwatch by saving the time public start(): void{ //Make sure the stop time is reset this.stopTime = null; //Get the time as close to returning from the function as possible this.startTime = performance.now(); } //Simulates stopping a stopwatch by saving the time public stop(): void{ //Set the stopTime as close to call time as possible this.stopTime = performance.now(); //If the startTime has not been set then reset stopTime if(this.startTime == null){ this.stopTime = null; } } //Resets all variables in the stopwatch public reset(): void{ //Make sure all variables are reset correctly this.startTime = null; this.stopTime = null; } //Returns the time in nanoseconds public getNano(): number{ return this.getTime() * 1000000; } //Returns the time in microseconds public getMicro(): number{ return this.getTime() * 1000; } //Returns the time in milliseconds public getMilli(): number{ return this.getTime(); } //Returns the time in seconds public getSecond(): number{ return this.getTime() / 1000; } //Returns the time in minutes public getMinute(): number{ return this.getTime() / 60000; } //Returns the time in hours public getHour(): number{ return this.getTime() / 3600000; } //Returns the time as a string at the 'best' resolution. (Goal is xxx.xxx) public getStr(): string{ //Get the current duraction from time return Stopwatch.getStr(this.getNano()); } public static getStr(nanoseconds: number): string{ let duration: number = nanoseconds; //Reduce the num,ber to the appropriate number of digits. (xxx.x). //This loop works down to seconds let resolution: TIME_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 minutes 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 let time: string = duration.toFixed(3); //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: throw new InvalidResult("timeResolution was invalid"); } //Return the string return time; } }