owncast/utils/performanceTimer.go
2022-03-16 22:49:27 -07:00

110 lines
2.2 KiB
Go

package utils
import (
"sort"
"sync"
"time"
)
var l = sync.Mutex{}
// The "start" timestamp of a timing event.
var _pointsInTime = make(map[string]time.Time)
// A collection of timestamp durations for returning the average of.
var _durationStorage = make(map[string][]float64)
// StartPerformanceMonitor will keep track of the start time of this event.
func StartPerformanceMonitor(key string) {
l.Lock()
if len(_durationStorage[key]) > 20 {
_durationStorage[key] = removeHighValue(_durationStorage[key])
}
_pointsInTime[key] = time.Now()
l.Unlock()
}
// GetAveragePerformance will return the average durations for the event.
func GetAveragePerformance(key string) float64 {
timestamp := _pointsInTime[key]
if timestamp.IsZero() {
return 0
}
l.Lock()
defer l.Unlock()
delta := time.Since(timestamp).Seconds()
_durationStorage[key] = append(_durationStorage[key], delta)
if len(_durationStorage[key]) < 8 {
return 0
}
_durationStorage[key] = removeHighValue(_durationStorage[key])
return Avg(_durationStorage[key])
}
func removeHighValue(values []float64) []float64 {
sort.Float64s(values)
return values[:len(values)-1]
}
// Avg will return the average value from a slice of float64s.
func Avg(values []float64) float64 {
total := 0.0
for _, number := range values {
total += number
}
average := total / float64(len(values))
return average
}
// Sum returns the sum of a slice of values.
func Sum(values []float64) float64 {
total := 0.0
for _, number := range values {
total += number
}
return total
}
// MinMax will return the min and max values from a slice of float64s.
func MinMax(array []float64) (float64, float64) {
max := array[0]
min := array[0]
for _, value := range array {
if max < value {
max = value
}
if min > value {
min = value
}
}
return min, max
}
func mean(input []float64) float64 {
sum := Sum(input)
return sum / float64(len(input))
}
// Median gets the median number in a slice of numbers.
func Median(input []float64) float64 {
if len(input) == 1 {
return input[0]
}
c := make([]float64, len(input))
copy(c, input)
var median float64
l := len(c)
if l%2 == 0 {
median = mean(c[l/2-1 : l/2+1])
} else {
median = c[l/2]
}
return median
}