Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# ExecutionTimer | ||
|
||
`ExecutionTimer` is a simple TypeScript class for measuring the execution time of code blocks. It provides methods to start, stop, and retrieve the duration of the timer. Additionally, it includes a function to get human-readable elapsed time. | ||
|
||
## Usage | ||
|
||
```typescript | ||
import { ExecutionTimer } from 'execution-timer'; | ||
|
||
// Create an instance of ExecutionTimer | ||
const timer = new ExecutionTimer(); | ||
|
||
// Start the timer | ||
timer.start(); | ||
|
||
// Code execution you want to measure | ||
for (let i = 0; i < 1000000; i++) { | ||
// Some computation | ||
} | ||
|
||
// Stop the timer | ||
timer.stop(); | ||
|
||
// Get and log the duration | ||
const duration = timer.getDuration(); | ||
console.log(`Execution time: ${duration} milliseconds`); | ||
|
||
// Get and log the human-readable elapsed time | ||
const elapsedTime = timer.getElapsedTime(); | ||
console.log(`Elapsed time: ${elapsedTime}`); | ||
|
||
``` | ||
|
||
You can use a custom execution ID to track multiple timers independently: | ||
|
||
```typescript | ||
const customTimer = new ExecutionTimer('customId'); | ||
|
||
// Start and stop the timer with the custom ID | ||
customTimer.start(); | ||
// Code execution | ||
customTimer.stop(); | ||
|
||
// Get the duration and human-readable elapsed time | ||
const customDuration = customTimer.getDuration(); | ||
const customElapsedTime = customTimer.getElapsedTime(); | ||
|
||
console.log(`Custom Timer Duration: ${customDuration} milliseconds`); | ||
console.log(`Custom Timer Elapsed Time: ${customElapsedTime}`); | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { ExecutionTimer } from "./executionTimer"; | ||
|
||
describe("ExecutionTimer", () => { | ||
let timer: ExecutionTimer; | ||
|
||
beforeEach(() => { | ||
timer = new ExecutionTimer(); | ||
}); | ||
|
||
it("should start the timer", () => { | ||
timer.start(); | ||
expect(timer.getStartDate()).toBeDefined(); | ||
}); | ||
|
||
it("should stop the timer", () => { | ||
timer.start(); | ||
timer.stop(); | ||
expect(timer.getEndDate()).toBeDefined(); | ||
}); | ||
|
||
it("should get the duration", () => { | ||
Check failure on line 21 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get the duration
|
||
jest.spyOn(performance, "now").mockReturnValueOnce(200); | ||
timer.start(); | ||
// Simulate some code execution time | ||
jest.spyOn(performance, "now").mockReturnValueOnce(1000); | ||
timer.stop(); | ||
expect(timer.getDuration()).toBe(800); | ||
}); | ||
|
||
it("should get the start date in ISO format", () => { | ||
timer.start(); | ||
expect(timer.getStartDate() instanceof Date).toBe(true); | ||
}); | ||
|
||
it("should get the end date in ISO format", () => { | ||
timer.start(); | ||
timer.stop(); | ||
expect(timer.getEndDate() instanceof Date).toBe(true); | ||
}); | ||
|
||
it("should get the duration with a custom execution ID", () => { | ||
Check failure on line 41 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get the duration with a custom execution ID
|
||
const customId = "customId"; | ||
jest.spyOn(performance, "now").mockReturnValueOnce(200); | ||
timer.start(customId); | ||
// Simulate some code execution time | ||
jest.spyOn(performance, "now").mockReturnValueOnce(2000); | ||
expect(timer.getDuration(customId)).toBe(1800); | ||
}); | ||
|
||
it("should get the start date with a custom execution ID", () => { | ||
const customId = "customId"; | ||
timer.start(customId); | ||
expect(timer.getStartDate(customId) instanceof Date).toBe(true); | ||
}); | ||
|
||
it("should get the end date with a custom execution ID", () => { | ||
const customId = "customId"; | ||
timer.start(customId); | ||
timer.stop(customId); | ||
expect(timer.getEndDate(customId) instanceof Date).toBe(true); | ||
}); | ||
|
||
it("should get human-readable elapsed time for a duration", () => { | ||
Check failure on line 63 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get human-readable elapsed time for a duration
|
||
jest.spyOn(performance, "now").mockReturnValueOnce(1000); | ||
timer.start(); | ||
// Simulate some code execution time | ||
jest.spyOn(performance, "now").mockReturnValueOnce(4000); | ||
timer.stop(); | ||
const elapsedTime = timer.getElapsedTime(); | ||
expect(elapsedTime).toMatch(/3 seconds/); | ||
}); | ||
|
||
it("should get human-readable elapsed time with hours and minutes", () => { | ||
Check failure on line 73 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get human-readable elapsed time with hours and minutes
|
||
jest.spyOn(performance, "now").mockReturnValueOnce(1000); | ||
timer.start(); | ||
// Advance time by 1 hour, 1 minute, and 5 seconds | ||
jest.spyOn(performance, "now").mockReturnValueOnce(3666000); | ||
timer.stop(); | ||
const elapsedTime = timer.getElapsedTime(); | ||
expect(elapsedTime).toMatch(/1 hour 1 minute 5 seconds/); | ||
}); | ||
|
||
it("should get human-readable elapsed time with milliseconds", () => { | ||
Check failure on line 83 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get human-readable elapsed time with milliseconds
|
||
jest.spyOn(performance, "now").mockReturnValueOnce(1000); | ||
timer.start(); | ||
jest.spyOn(performance, "now").mockReturnValueOnce(1123); | ||
timer.stop(); | ||
const elapsedTime = timer.getElapsedTime(); | ||
expect(elapsedTime).toMatch(/123 ms/); | ||
}); | ||
|
||
it("should return undefined for getElapsedTime when timer is not started", () => { | ||
const elapsedTime = timer.getElapsedTime(); | ||
expect(elapsedTime).toBeUndefined(); | ||
}); | ||
|
||
// it("should return undefined for getElapsedTime when timer is not stopped", () => { | ||
// timer.start(); | ||
// const elapsedTime = timer.getElapsedTime(); | ||
// expect(elapsedTime).toBeUndefined(); | ||
// }); | ||
|
||
it("should get human-readable elapsed time with a custom execution ID", () => { | ||
Check failure on line 103 in src/timer/executionTimer.spec.ts GitHub Actions / Tests annotations (🧪 jest-coverage-report-action)ExecutionTimer > should get human-readable elapsed time with a custom execution ID
|
||
const customId = "customId"; | ||
jest.spyOn(performance, "now").mockReturnValueOnce(1000); | ||
timer.start(customId); | ||
jest.spyOn(performance, "now").mockReturnValueOnce(6000); | ||
timer.stop(customId); | ||
const elapsedTime = timer.getElapsedTime(customId); | ||
expect(elapsedTime).toMatch(/5 seconds/); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/** | ||
* A class for measuring the execution time of code blocks. | ||
*/ | ||
export class ExecutionTimer { | ||
private timer: { [key: string]: { startTime: number; endTime: number } } = {}; | ||
|
||
/** | ||
* Creates an instance of ExecutionTimer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
*/ | ||
constructor(executionId?: string) { | ||
this.timer[executionId ?? "default"] = { | ||
startTime: 0, | ||
endTime: 0, | ||
}; | ||
} | ||
|
||
/** | ||
* Starts the execution timer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
*/ | ||
start(executionId?: string) { | ||
this.timer[executionId ?? "default"] = { | ||
startTime: performance.now(), | ||
endTime: 0, | ||
}; | ||
} | ||
|
||
/** | ||
* Stops the execution timer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
*/ | ||
stop(executionId?: string) { | ||
if (this.timer[executionId ?? "default"]?.startTime) { | ||
this.timer[executionId ?? "default"].endTime = performance.now(); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the duration of the execution timer in milliseconds. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
* @returns The duration of the execution timer in milliseconds. | ||
*/ | ||
getDuration(executionId?: string) { | ||
const timerId = executionId ?? "default"; | ||
if (this.timer[executionId ?? "default"]?.startTime) { | ||
if (!this.timer[executionId ?? "default"].endTime) { | ||
this.stop(timerId); | ||
} | ||
return ( | ||
this.timer[executionId ?? "default"].endTime - | ||
this.timer[executionId ?? "default"].startTime | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the start date of the execution timer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
* @returns The start date of the execution timer. | ||
*/ | ||
getStartDate(executionId?: string): Date | undefined { | ||
if (this.timer[executionId ?? "default"]?.startTime) { | ||
return new Date(this.timer[executionId ?? "default"]?.startTime); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the end date of the execution timer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
* @returns The end date of the execution timer. | ||
*/ | ||
getEndDate(executionId?: string): Date | undefined { | ||
if (this.timer[executionId ?? "default"]?.endTime) { | ||
return new Date(this.timer[executionId ?? "default"]?.endTime); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the human-readable elapsed time of the execution timer. | ||
* @param executionId - An optional identifier for the execution timer. Defaults to 'default'. | ||
* @returns A string representing the human-readable elapsed time. | ||
*/ | ||
getElapsedTime(executionId?: string): string | undefined { | ||
const duration = this.getDuration(executionId); | ||
if (duration === undefined) { | ||
return undefined; | ||
} | ||
|
||
const milliseconds = Math.floor(duration % 1000); | ||
const seconds = Math.floor((duration / 1000) % 60); | ||
const minutes = Math.floor((duration / (1000 * 60)) % 60); | ||
const hours = Math.floor((duration / (1000 * 60 * 60)) % 24); | ||
|
||
const parts = []; | ||
|
||
if (hours > 0) { | ||
parts.push(`${hours} hour${hours > 1 ? 's' : ''}`); | ||
Check warning on line 98 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
Check warning on line 98 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🌿 Branch is not covered
|
||
} | ||
Check warning on line 99 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
|
||
if (minutes > 0) { | ||
parts.push(`${minutes} minute${minutes > 1 ? 's' : ''}`); | ||
Check warning on line 101 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
Check warning on line 101 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🌿 Branch is not covered
|
||
} | ||
Check warning on line 102 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
|
||
if (seconds > 0) { | ||
parts.push(`${seconds} second${seconds > 1 ? 's' : ''}`); | ||
Check warning on line 104 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
Check warning on line 104 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🌿 Branch is not covered
|
||
} | ||
Check warning on line 105 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
|
||
if (milliseconds > 0) { | ||
parts.push(`${milliseconds} ms`); | ||
} | ||
Check warning on line 108 in src/timer/executionTimer.ts GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)🧾 Statement is not covered
|
||
|
||
return parts.join(' '); | ||
} | ||
} |