performanceTimer.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package utils
  2. import (
  3. "sort"
  4. "sync"
  5. "time"
  6. )
  7. var l = sync.Mutex{}
  8. // The "start" timestamp of a timing event.
  9. var _pointsInTime = make(map[string]time.Time)
  10. // A collection of timestamp durations for returning the average of.
  11. var _durationStorage = make(map[string][]float64)
  12. // StartPerformanceMonitor will keep track of the start time of this event.
  13. func StartPerformanceMonitor(key string) {
  14. l.Lock()
  15. if len(_durationStorage[key]) > 20 {
  16. _durationStorage[key] = removeHighValue(_durationStorage[key])
  17. }
  18. _pointsInTime[key] = time.Now()
  19. l.Unlock()
  20. }
  21. // GetAveragePerformance will return the average durations for the event.
  22. func GetAveragePerformance(key string) float64 {
  23. timestamp := _pointsInTime[key]
  24. if timestamp.IsZero() {
  25. return 0
  26. }
  27. l.Lock()
  28. defer l.Unlock()
  29. delta := time.Since(timestamp).Seconds()
  30. _durationStorage[key] = append(_durationStorage[key], delta)
  31. if len(_durationStorage[key]) < 8 {
  32. return 0
  33. }
  34. _durationStorage[key] = removeHighValue(_durationStorage[key])
  35. return Avg(_durationStorage[key])
  36. }
  37. func removeHighValue(values []float64) []float64 {
  38. sort.Float64s(values)
  39. return values[:len(values)-1]
  40. }
  41. // Avg will return the average value from a slice of float64s.
  42. func Avg(values []float64) float64 {
  43. total := 0.0
  44. for _, number := range values {
  45. total += number
  46. }
  47. average := total / float64(len(values))
  48. return average
  49. }
  50. // Sum returns the sum of a slice of values.
  51. func Sum(values []float64) float64 {
  52. total := 0.0
  53. for _, number := range values {
  54. total += number
  55. }
  56. return total
  57. }
  58. // MinMax will return the min and max values from a slice of float64s.
  59. func MinMax(array []float64) (float64, float64) {
  60. max := array[0]
  61. min := array[0]
  62. for _, value := range array {
  63. if max < value {
  64. max = value
  65. }
  66. if min > value {
  67. min = value
  68. }
  69. }
  70. return min, max
  71. }
  72. func mean(input []float64) float64 {
  73. sum := Sum(input)
  74. return sum / float64(len(input))
  75. }
  76. // Median gets the median number in a slice of numbers.
  77. func Median(input []float64) float64 {
  78. if len(input) == 1 {
  79. return input[0]
  80. }
  81. c := make([]float64, len(input))
  82. copy(c, input)
  83. var median float64
  84. l := len(c)
  85. if l%2 == 0 {
  86. median = mean(c[l/2-1 : l/2+1])
  87. } else {
  88. median = c[l/2]
  89. }
  90. return median
  91. }