78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
package timingbench
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
"gonum.org/v1/gonum/stat"
|
|
)
|
|
|
|
// TimingResult holds the timing results for a function execution.
|
|
type TimingResult struct {
|
|
Min time.Duration
|
|
Max time.Duration
|
|
Mean time.Duration
|
|
Median time.Duration
|
|
StartTime time.Time
|
|
EndTime time.Time
|
|
Duration time.Duration
|
|
Iterations int
|
|
}
|
|
|
|
// String returns a formatted string representation of the TimingResult.
|
|
func (r TimingResult) String() string {
|
|
return fmt.Sprintf(
|
|
"Start Time: %v, End Time: %v, Duration: %v, Iterations: %d, Min: %v, Max: %v, Mean: %v, Median: %v",
|
|
r.StartTime, r.EndTime, r.Duration, r.Iterations, r.Min, r.Max, r.Mean, r.Median,
|
|
)
|
|
}
|
|
|
|
// TimeFunction runs the given function fn a specified number of times and returns the timing results.
|
|
// It supports context for cancellation.
|
|
func TimeFunction(ctx context.Context, fn func() error, iterations int) (TimingResult, error) {
|
|
if iterations <= 0 {
|
|
return TimingResult{}, errors.New("iterations must be greater than 0")
|
|
}
|
|
|
|
times := make([]float64, 0, iterations)
|
|
startTime := time.Now().UTC()
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
select {
|
|
case <-ctx.Done():
|
|
return TimingResult{}, ctx.Err()
|
|
default:
|
|
iterStart := time.Now().UTC()
|
|
if err := fn(); err != nil {
|
|
return TimingResult{}, err
|
|
}
|
|
elapsed := time.Since(iterStart)
|
|
times = append(times, float64(elapsed))
|
|
}
|
|
}
|
|
|
|
endTime := time.Now().UTC()
|
|
totalDuration := endTime.Sub(startTime)
|
|
|
|
sort.Float64s(times)
|
|
|
|
min := time.Duration(times[0])
|
|
max := time.Duration(times[len(times)-1])
|
|
mean := time.Duration(stat.Mean(times, nil))
|
|
median := time.Duration(stat.Quantile(0.5, stat.Empirical, times, nil))
|
|
|
|
return TimingResult{
|
|
Min: min,
|
|
Max: max,
|
|
Mean: mean,
|
|
Median: median,
|
|
StartTime: startTime,
|
|
EndTime: endTime,
|
|
Duration: totalDuration,
|
|
Iterations: iterations,
|
|
}, nil
|
|
}
|