timecache

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2026 License: MPL-2.0 Imports: 2 Imported by: 9

README

go-timecache: Ultra-fast time caching for high-performance Go applications

an AGILira library

CI/CD Security Go Report Card codecov GoDoc

FeaturesQuick StartPerformanceUsageAPI ReferenceDocumentation

Complete documentation is available at: https://agilira.github.io/go-timecache/

Part of our Xantos Core, go-timecache provides zero-allocation access to cached time values, eliminating the performance overhead of repeated time.Now() calls in high-throughput scenarios like logging, metrics collection, and real-time data processing.

Features

  • Zero-allocation time access: Get current time without heap allocations
  • Configurable precision: Choose your ideal balance between accuracy and performance
  • Thread-safe: Safe for concurrent use from multiple goroutines
  • Simple API: Drop-in replacement for time.Now() with minimal code changes
  • Multiple formats: Access time as time.Time, nanoseconds, or formatted string

Compatibility and Support

go-timecache is designed for Go 1.23+ environments and follows Long-Term Support guidelines to ensure consistent performance across production deployments.

Performance

Benchmarks show dramatic improvements over standard time.Now():

AMD Ryzen 5 7520U with Radeon Graphics
BenchmarkTimeNow-8                      25118025           42.98 ns/op          0 B/op         0 allocs/op
BenchmarkCachedTime-8                   1000000000         0.3549 ns/op         0 B/op         0 allocs/op
BenchmarkCachedTimeNano-8               1000000000         0.3574 ns/op         0 B/op         0 allocs/op
BenchmarkTimeNowUnixNano-8              27188656           42.68 ns/op          0 B/op         0 allocs/op
BenchmarkCachedTimeParallel-8           1000000000         0.1737 ns/op         0 B/op         0 allocs/op
BenchmarkTimeNowParallel-8              184139052          6.417 ns/op          0 B/op         0 allocs/op

Reproduce benchmarks:

go test -bench=. -benchmem
  • CachedTime is ~121x faster than time.Now()
  • CachedTimeParallel is ~37x faster than parallel time.Now()
  • Zero heap allocations in all operations

Quick Start

Installation
go get github.com/agilira/go-timecache

Usage

import "github.com/agilira/go-timecache"

// Using the default global cache
now := timecache.CachedTime()
nanos := timecache.CachedTimeNano()  // Zero allocation!

// Create your own cache with custom settings
tc := timecache.NewWithResolution(1 * time.Millisecond)
defer tc.Stop()  // Important: remember to stop when done

customTime := tc.CachedTime()

API Reference

Global Functions
  • CachedTime() time.Time: Get current time from default cache
  • CachedTimeNano() int64: Get nanoseconds since epoch (zero allocation)
  • CachedTimeString() string: Get formatted time string
  • DefaultCache() *TimeCache: Access the default TimeCache instance
  • StopDefaultCache(): Stop the default cache (use during shutdown)
TimeCache Methods
  • New() *TimeCache: Create a new cache with default settings
  • NewWithResolution(resolution time.Duration) *TimeCache: Custom resolution
  • CachedTime() time.Time: Get current time from this cache
  • CachedTimeNano() int64: Get nanoseconds from this cache (zero allocation)
  • CachedTimeString() string: Get formatted time from this cache
  • Resolution() time.Duration: Get this cache's resolution
  • Stop(): Stop this cache's background updater

Documentation

https://agilira.github.io/go-timecache/

License

go-timecache is licensed under the Mozilla Public License 2.0.


go-timecache • an AGILira library

Documentation

Overview

Package timecache provides ultra-fast time caching for high-performance Go applications.

TimeCache eliminates the performance overhead of repeated time.Now() calls by maintaining a cached timestamp that is updated at configurable intervals. This is particularly beneficial in high-throughput scenarios like logging, metrics collection, and real-time data processing where frequent timestamp generation can become a bottleneck.

Key Features:

  • Zero-allocation time access for maximum performance
  • Configurable update resolution (precision vs CPU usage)
  • Thread-safe concurrent access from multiple goroutines
  • Multiple output formats: time.Time, nanoseconds, and formatted strings
  • Global default instance for convenience

Performance Benefits:

  • CachedTime() is ~121x faster than time.Now()
  • CachedTimeNano() provides zero-allocation access to Unix nanoseconds
  • Parallel access scales better than standard time.Now()

Example Usage:

// Using the global default cache
now := timecache.CachedTime()
nano := timecache.CachedTimeNano() // Zero allocation!

// Create custom cache with specific resolution
tc := timecache.NewWithResolution(1 * time.Millisecond)
defer tc.Stop()
customTime := tc.CachedTime()

Copyright (c) 2025 AGILira - A. Giordano Series: an AGLIra fragment SPDX-License-Identifier: MPL-2.0

Example
// Using the default global cache - no setup required!
now := timecache.CachedTime()
fmt.Printf("Current time: %v\n", now)

// Get time as Unix nano (zero allocation - fastest method)
nano := timecache.CachedTimeNano()
fmt.Printf("Nanoseconds since epoch: %d\n", nano)

// Get formatted time string (useful for logging)
timeStr := timecache.CachedTimeString()
fmt.Printf("ISO timestamp: %s\n", timeStr)
Example (HighThroughputUsage)

High throughput usage

// This example demonstrates a typical high-throughput usage pattern
// where you need to timestamp many events with minimal overhead

// In your init() or setup code:
tc := timecache.New()
defer tc.Stop()

// Simulate processing multiple events
process := func(id int) {
	// Get timestamp with zero allocation (fastest method)
	timestamp := tc.CachedTimeNano()

	// Use timestamp in your high-performance code
	// This could be logging, metrics, or event processing
	_ = fmt.Sprintf("Event %d processed at %d", id, timestamp)
}

// Process multiple events with minimal overhead
for i := 0; i < 10; i++ {
	process(i)
}

// All events processed with consistent, fast timestamps
fmt.Println("All events processed with cached timestamps")

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CachedTime

func CachedTime() time.Time

CachedTime returns the cached time as a time.Time value from the default cache. This function converts the internal nanosecond timestamp to a time.Time for convenient use with Go's time package functions.

Example:

now := timecache.CachedTime()
fmt.Printf("Current time: %v\n", now)

func CachedTimeNano

func CachedTimeNano() int64

CachedTimeNano returns the cached time in nanoseconds since Unix epoch from the default cache. This function provides zero-allocation access to the current timestamp and is the fastest way to get time information.

The returned value represents nanoseconds since January 1, 1970 UTC.

Example:

nano := timecache.CachedTimeNano()
fmt.Printf("Timestamp: %d nanoseconds\n", nano)

func CachedTimeString

func CachedTimeString() string

CachedTimeString returns the cached time formatted as an RFC3339Nano string from the default cache. The returned string is in UTC timezone and follows the format: "2006-01-02T15:04:05.999999999Z07:00"

This function is useful for logging, API responses, or any scenario where a standardized time string format is required.

Example:

timeStr := timecache.CachedTimeString()
fmt.Printf("ISO timestamp: %s\n", timeStr)

func StopDefaultCache

func StopDefaultCache()

StopDefaultCache stops the global default time cache. After calling this function, the default cache will no longer be updated and the background goroutine will terminate.

This function is mainly intended for testing and shutdown scenarios. In normal application usage, the default cache should remain running.

Example:

// During application shutdown
timecache.StopDefaultCache()

Types

type TimeCache

type TimeCache struct {
	// contains filtered or unexported fields
}

TimeCache provides cached time access to eliminate time.Now() allocations. It is optimized for high-throughput scenarios where multiple goroutines need frequent access to the current time with minimal overhead.

A TimeCache maintains an internal timestamp that is updated at regular intervals by a background goroutine. All access methods are thread-safe and provide zero-allocation access to the cached time value.

The cache automatically starts updating when created and must be stopped explicitly to prevent goroutine leaks.

func DefaultCache

func DefaultCache() *TimeCache

DefaultCache returns the global default TimeCache instance. This allows access to the default cache for advanced operations like checking resolution or stopping the cache.

Example:

defaultCache := timecache.DefaultCache()
fmt.Printf("Default cache resolution: %v\n", defaultCache.Resolution())
Example
// Access the default cache for advanced operations
defaultCache := timecache.DefaultCache()

// Check the default resolution
fmt.Printf("Default cache resolution: %v\n", defaultCache.Resolution())

// Use the default cache directly
now := defaultCache.CachedTime()
fmt.Printf("Time from default cache: %v\n", now)

func New

func New() *TimeCache

New creates a new TimeCache with default resolution (500µs).

The default resolution provides a good balance between accuracy and CPU usage for most high-throughput applications. The cache starts updating immediately and must be stopped explicitly to prevent goroutine leaks.

Example:

tc := timecache.New()
defer tc.Stop()
now := tc.CachedTime()
Example
// Create a custom time cache with 1ms resolution
tc := timecache.NewWithResolution(1 * time.Millisecond)
defer tc.Stop() // Important: stop the cache when done to prevent goroutine leak

// Use the custom cache instance
now := tc.CachedTime()
fmt.Printf("Custom cache time: %v\n", now)
fmt.Printf("Cache resolution: %v\n", tc.Resolution())

func NewWithResolution

func NewWithResolution(resolution time.Duration) *TimeCache

NewWithResolution creates a new TimeCache with custom update resolution.

The resolution parameter controls how frequently the cached time is updated. Smaller values provide more accurate timestamps but consume more CPU.

Recommended resolution values:

  • 100µs to 500µs: High precision, suitable for real-time systems
  • 1ms to 10ms: Balanced performance, good for most applications
  • >10ms: Minimal CPU impact, suitable for non-critical timing

The cache starts updating immediately and must be stopped explicitly to prevent goroutine leaks.

Example:

// High precision cache for real-time logging
tc := timecache.NewWithResolution(100 * time.Microsecond)
defer tc.Stop()

// Balanced cache for general use
tc2 := timecache.NewWithResolution(1 * time.Millisecond)
defer tc2.Stop()
Example
// Create different caches for different precision needs

// High precision for real-time systems
highPrecision := timecache.NewWithResolution(100 * time.Microsecond)
defer highPrecision.Stop()

// Balanced for general use
balanced := timecache.NewWithResolution(1 * time.Millisecond)
defer balanced.Stop()

// Low precision for non-critical timing
lowPrecision := timecache.NewWithResolution(10 * time.Millisecond)
defer lowPrecision.Stop()

fmt.Printf("High precision resolution: %v\n", highPrecision.Resolution())
fmt.Printf("Balanced resolution: %v\n", balanced.Resolution())
fmt.Printf("Low precision resolution: %v\n", lowPrecision.Resolution())

func (*TimeCache) CachedTime

func (tc *TimeCache) CachedTime() time.Time

CachedTime returns the cached time as a time.Time value. This method converts the internal nanosecond timestamp to a time.Time for convenient use with Go's time package functions.

Example:

tc := timecache.New()
defer tc.Stop()
now := tc.CachedTime()
fmt.Printf("Current time: %v\n", now)

func (*TimeCache) CachedTimeNano

func (tc *TimeCache) CachedTimeNano() int64

CachedTimeNano returns the cached time in nanoseconds since Unix epoch. This method provides zero-allocation access to the current timestamp and is the fastest way to get time information from the cache.

The returned value represents nanoseconds since January 1, 1970 UTC.

Example:

tc := timecache.New()
defer tc.Stop()
nano := tc.CachedTimeNano()
fmt.Printf("Timestamp: %d nanoseconds\n", nano)
Example
// Create a new cache with default settings
tc := timecache.New()
defer tc.Stop()

// Get cached time as nanoseconds (zero allocation - fastest method)
nano := tc.CachedTimeNano()
fmt.Printf("Nanoseconds: %d\n", nano)

// Convert nanoseconds to time.Time if needed
tm := time.Unix(0, nano)
fmt.Printf("Converted to time.Time: %v\n", tm)

// Multiple calls return the same value within the cache resolution
nano2 := tc.CachedTimeNano()
fmt.Printf("Same value: %t\n", nano == nano2)

func (*TimeCache) CachedTimeString

func (tc *TimeCache) CachedTimeString() string

CachedTimeString returns the cached time formatted as an RFC3339Nano string. The returned string is in UTC timezone and follows the format: "2006-01-02T15:04:05.999999999Z07:00"

This method is useful for logging, API responses, or any scenario where a standardized time string format is required.

Example:

tc := timecache.New()
defer tc.Stop()
timeStr := tc.CachedTimeString()
fmt.Printf("ISO timestamp: %s\n", timeStr)
Example
// Create a cache for logging scenarios
tc := timecache.New()
defer tc.Stop()

// Get formatted time string (useful for logs, APIs, etc.)
timeStr := tc.CachedTimeString()
fmt.Printf("Log entry: [%s] User logged in\n", timeStr)

// Multiple calls within cache resolution return same formatted string
timeStr2 := tc.CachedTimeString()
fmt.Printf("Same timestamp: %t\n", timeStr == timeStr2)

func (*TimeCache) Resolution

func (tc *TimeCache) Resolution() time.Duration

Resolution returns the update frequency of this cache. This is the interval at which the cached time value is refreshed by the background updater goroutine.

Example:

tc := timecache.NewWithResolution(1 * time.Millisecond)
defer tc.Stop()
fmt.Printf("Cache updates every: %v\n", tc.Resolution())

func (*TimeCache) Stop

func (tc *TimeCache) Stop()

Stop permanently stops the time cache updater. After calling Stop, the cached time value will no longer be updated and the background goroutine will terminate.

It is important to call Stop to prevent goroutine leaks when the cache is no longer needed.

Example:

tc := timecache.New()
// ... use the cache ...
tc.Stop() // Clean up resources

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL