npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@universal-packages/time-measurer

v2.1.0

Published

Utility to measure routines times with precision

Downloads

37,869

Readme

Time Measurer

npm version Testing codecov

Time Measurer is a simple wrap for process.hrtime.bigint to measure time with procession and express that time easily through formatted representations, anytime you want to express how much a query or a request took at code level you may want to give this a try.

Getting Started

npm install @universal-packages/time-measurer

Usage

TimeMeasurer class

The TimeMeasurer class is a simple utility for measuring time with precision. It wraps process.hrtime.bigint() for Node.js environments and falls back to performance.now() in browser environments.

import { TimeMeasurer } from '@universal-packages/time-measurer'

const measurer = TimeMeasurer.start()
// ... some operation
const measurement = measurer.finish()

console.log(measurement.toString()) // "123.456ms"

Constructor constructor

new TimeMeasurer()

Creates a new TimeMeasurer instance. The measurer is not started automatically.

Instance Methods

start

start(): void

Starts the time measurement. This method will throw an error if the measurer has already been started.

const measurer = new TimeMeasurer()
measurer.start()
// ... some operation
const measurement = measurer.finish()

finish

finish(): Measurement

Finishes the time measurement and returns a Measurement instance containing the elapsed time.

const measurer = new TimeMeasurer()
measurer.start()
// ... some operation
const measurement = measurer.finish()

Static Methods

start

static start(): TimeMeasurer

Creates a new TimeMeasurer instance and immediately starts it. This is a convenience method for quick measurements.

const measurer = TimeMeasurer.start()
// ... some operation
const measurement = measurer.finish()

Measurement class

The Measurement class represents a measured time duration with various formatting options, convenient accessors for different time units, arithmetic operations, and comparison capabilities.

import { Measurement, TimeMeasurer } from '@universal-packages/time-measurer'

const measurer = TimeMeasurer.start()
// ... some operation
const measurement = measurer.finish()

console.log(measurement.hours) // 0
console.log(measurement.minutes) // 0
console.log(measurement.seconds) // 1
console.log(measurement.milliseconds) // 234.567

// Arithmetic operations
const measurement1 = new Measurement(1000000000n) // 1 second
const measurement2 = new Measurement(2000000000n) // 2 seconds

const sum = measurement1.add(measurement2)
console.log(sum.toString()) // "3.000sec"

// Comparison operations
console.log(measurement1 < measurement2) // true
console.log(measurement1.lessThan(measurement2)) // true

Constructor constructor

new Measurement(nanoseconds: bigint)

Creates a new Measurement instance from nanoseconds. This is typically called internally by TimeMeasurer.

Properties

  • hours: number - The hours component of the measurement
  • minutes: number - The minutes component of the measurement
  • seconds: number - The seconds component of the measurement
  • milliseconds: number - The milliseconds component (including fractional part)
  • nanoseconds: bigint - The total nanoseconds of the measurement

Instance Methods

Arithmetic Operations

add
add(other: Measurement): Measurement

Adds another measurement to this one and returns a new measurement with the sum of both times.

const measurement1 = new Measurement(1000000000n) // 1 second
const measurement2 = new Measurement(500000000n)  // 0.5 seconds
const sum = measurement1.add(measurement2)
console.log(sum.toString()) // "1.500sec"
subtract
subtract(other: Measurement): Measurement

Subtracts another measurement from this one and returns a new measurement with the difference. If the result would be negative, returns a zero measurement.

const measurement1 = new Measurement(2000000000n) // 2 seconds
const measurement2 = new Measurement(500000000n)  // 0.5 seconds
const difference = measurement1.subtract(measurement2)
console.log(difference.toString()) // "1.500sec"

// Negative results are clamped to zero
const negative = measurement2.subtract(measurement1)
console.log(negative.toString()) // "0.00ms"

Comparison Methods

equals
equals(other: Measurement): boolean

Checks if this measurement is equal to another measurement.

const measurement1 = new Measurement(1000000000n)
const measurement2 = new Measurement(1000000000n)
console.log(measurement1.equals(measurement2)) // true
lessThan
lessThan(other: Measurement): boolean

Checks if this measurement is less than another measurement.

const measurement1 = new Measurement(500000000n)  // 0.5 seconds
const measurement2 = new Measurement(1000000000n) // 1 second
console.log(measurement1.lessThan(measurement2)) // true
greaterThan
greaterThan(other: Measurement): boolean

Checks if this measurement is greater than another measurement.

console.log(measurement2.greaterThan(measurement1)) // true
lessThanOrEqual
lessThanOrEqual(other: Measurement): boolean

Checks if this measurement is less than or equal to another measurement.

greaterThanOrEqual
greaterThanOrEqual(other: Measurement): boolean

Checks if this measurement is greater than or equal to another measurement.

Operator Overloading

The Measurement class supports JavaScript's native comparison and arithmetic operators through Symbol.toPrimitive:

const measurement1 = new Measurement(1000000000n) // 1 second
const measurement2 = new Measurement(2000000000n) // 2 seconds

// Comparison operators (recommended)
console.log(measurement1 < measurement2)  // true
console.log(measurement1 > measurement2)  // false
console.log(measurement1 <= measurement2) // true
console.log(measurement1 >= measurement2) // false
console.log(measurement1 == measurement2) // false
console.log(measurement1 != measurement2) // true

// Arithmetic operators (returns numbers in nanoseconds)
console.log(measurement1 + measurement2) // 3000000000 (nanoseconds)
console.log(measurement2 - measurement1) // 1000000000 (nanoseconds)

// For arithmetic operations that return Measurement objects, use methods:
const sum = measurement1.add(measurement2)     // Returns Measurement
const diff = measurement2.subtract(measurement1) // Returns Measurement

Method Chaining

All arithmetic methods return new Measurement instances, allowing for method chaining:

const base = new Measurement(1000000000n)    // 1 second
const half = new Measurement(500000000n)     // 0.5 seconds
const quarter = new Measurement(250000000n)  // 0.25 seconds

const result = base.add(half).subtract(quarter)
console.log(result.toString()) // "1.250sec"

toString

toString(format?: TimeFormat): string

Converts the measurement to a formatted string representation.

const measurement = new Measurement(1234567890n)

console.log(measurement.toString('Human')) // "1.234sec"
console.log(measurement.toString('Condensed')) // "1.234"
console.log(measurement.toString('Expressive')) // "1.234 Seconds"
TimeFormat
  • 'Human' (default): User-friendly format like "1.234sec", "2min 30.500sec", "1hrs 15min 30.250sec"
  • 'Condensed': Compact format like "1.234", "02:30.500", "01:15:30.250"
  • 'Expressive': Verbose format like "1.234 Seconds", "2 Minutes, and 30.500 Seconds"

toDate

toDate(): Date

Converts the measurement to a JavaScript Date object with the time components.

const measurement = new Measurement(3661000000000n) // 1 hour, 1 minute, 1 second
const date = measurement.toDate()
console.log(date.getHours()) // 1
console.log(date.getMinutes()) // 1
console.log(date.getSeconds()) // 1

Benchmark class

The Benchmark class provides functionality for running performance benchmarks with support for multiple iterations, warmup runs, and statistical analysis.

import { Benchmark } from '@universal-packages/time-measurer'

const benchmark = new Benchmark({
  iterations: 1000,
  warmupIterations: 100,
  name: 'Array sorting benchmark'
})

const result = benchmark.run(() => {
  const arr = Array.from({ length: 1000 }, () => Math.random())
  arr.sort()
})

console.log(`Average: ${result.average.toString()}`)
console.log(`Min: ${result.min.toString()}`)
console.log(`Max: ${result.max.toString()}`)

Constructor constructor

new Benchmark(options?: BenchmarkOptions)

Creates a new Benchmark instance with the specified options.

BenchmarkOptions

  • iterations: number (default: 1) Number of iterations to run for the actual benchmark measurement.
  • warmupIterations: number (default: 0) Number of warmup iterations to run before the actual measurement to stabilize performance.
  • name: string (default: 'Unnamed Benchmark') A descriptive name for the benchmark.

Instance Methods

run

run(fn: () => void): BenchmarkResult

Runs a synchronous function benchmark and returns detailed results including statistics.

const benchmark = new Benchmark({ iterations: 100 })

const result = benchmark.run(() => {
  // Your code to benchmark
  heavyComputation()
})

console.log(`Completed ${result.iterations} iterations`)
console.log(`Average time: ${result.average.toString()}`)

runAsync

runAsync(fn: () => Promise<void>): Promise<BenchmarkResult>

Runs an asynchronous function benchmark and returns detailed results including statistics.

const benchmark = new Benchmark({ iterations: 50 })

const result = await benchmark.runAsync(async () => {
  // Your async code to benchmark
  await asyncOperation()
})

console.log(`Average time: ${result.average.toString()}`)

BenchmarkResult

The result object returned by run() and runAsync() contains:

  • name: string - Name of the benchmark
  • iterations: number - Number of iterations performed
  • warmupIterations: number - Number of warmup iterations performed
  • measurements: Measurement[] - Array of all individual measurements
  • min: Measurement - Fastest measurement
  • max: Measurement - Slowest measurement
  • average: Measurement - Average of all measurements
  • total: Measurement - Total time for all iterations

TimeProfiler class

The TimeProfiler class provides advanced profiling capabilities with named checkpoints, memory tracking, and session management for detailed performance analysis.

import { TimeProfiler } from '@universal-packages/time-measurer'

const profiler = TimeProfiler.start('Database Operations')

// Start some operation
const users = await db.users.findMany()
profiler.checkpoint('Users loaded')

// Another operation
const posts = await db.posts.findMany()
profiler.checkpoint('Posts loaded')

// Finish profiling
const checkpoints = profiler.stop('Complete')

checkpoints.forEach((cp) => {
  console.log(`${cp.name}: ${cp.measurement.toString()}`)
})

Constructor constructor

new TimeProfiler(options?: ProfilerOptions)

Creates a new TimeProfiler instance with the specified options.

ProfilerOptions

  • name: string (default: 'Profiler Session') A descriptive name for the profiling session.
  • trackMemory: boolean (default: false) Whether to track memory usage and deltas between checkpoints.

Properties

checkpoints

readonly checkpoints: ProfilerCheckpoint[]

Returns a copy of all checkpoints recorded so far.

lastCheckpoint

readonly lastCheckpoint: ProfilerCheckpoint | undefined

Returns the most recently recorded checkpoint, or undefined if none exist.

isRunning

readonly isRunning: boolean

Returns true if the profiler is currently active and measuring time.

elapsed

readonly elapsed: Measurement | undefined

Returns the current elapsed time since the profiler was started, or undefined if not started.

Instance Methods

start

start(): void

Starts the profiling session. Throws an error if already started.

const profiler = new TimeProfiler()
profiler.start()

checkpoint

checkpoint(name: string): Measurement

Creates a named checkpoint and returns the measurement from the start time. Throws an error if not started.

profiler.checkpoint('Database connected')
// ... more operations
profiler.checkpoint('Data processed')

getCheckpoint

getCheckpoint(name: string): ProfilerCheckpoint | undefined

Retrieves a specific checkpoint by name.

const dbCheckpoint = profiler.getCheckpoint('Database connected')
if (dbCheckpoint) {
  console.log(`DB connection took: ${dbCheckpoint.measurement.toString()}`)
}

stop

stop(finalCheckpointName?: string): ProfilerCheckpoint[]

Stops the profiler, creates a final checkpoint, and returns all checkpoints.

const allCheckpoints = profiler.stop('Session Complete')

reset

reset(): void

Resets the profiler state to start a new session.

profiler.reset()
profiler.start() // Ready for a new session

Static Methods

start

static start(name?: string): TimeProfiler

Creates and immediately starts a new TimeProfiler instance.

const profiler = TimeProfiler.start('API Request Processing')

ProfilerCheckpoint

Each checkpoint contains:

  • name: string - Name/label for the checkpoint
  • measurement: Measurement - Time elapsed from start to this checkpoint
  • timestamp: Date - When the checkpoint was created
  • memoryUsage: number (optional) - Memory usage in bytes (if tracking enabled)
  • memoryDelta: number (optional) - Memory change from previous checkpoint (if tracking enabled)

Memory Tracking Example

const profiler = new TimeProfiler({ trackMemory: true })
profiler.start()

// Create some data
const largeArray = new Array(1000000).fill('data')
const checkpoint1 = profiler.checkpoint('Array created')

// Process data
largeArray.forEach((item) => item.toUpperCase())
const checkpoint2 = profiler.checkpoint('Array processed')

console.log(`Memory at checkpoint 1: ${checkpoint1.memoryUsage} bytes`)
console.log(`Memory delta: ${checkpoint2.memoryDelta} bytes`)

Sleep class

The Sleep class provides a simple utility for creating delays in asynchronous code using human-readable time strings. It leverages the ms library for flexible time string parsing.

import { Sleep } from '@universal-packages/time-measurer'

// Wait for 2 seconds
await Sleep.for('2s')

// Wait for 1.5 seconds
await Sleep.for('1500ms')

// Wait for 2 minutes
await Sleep.for('2m')

// Wait for 1 hour
await Sleep.for('1h')

Static Methods

for

static for(timeString: StringValue): Promise<void>

Creates a delay for the specified duration using a human-readable time string. Returns a Promise that resolves after the specified time has elapsed.

The timeString parameter accepts the same format as the ms library

Typescript

This library is developed in TypeScript and shipped fully typed.

Contributing

The development of this library happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving this library.

License

MIT licensed.