Skip to content

Commit

Permalink
Merge pull request #33 from gofiber/add_timestamp_calculator
Browse files Browse the repository at this point in the history
Add timestamp calculation functionality
  • Loading branch information
ReneWerner87 authored Oct 19, 2022
2 parents 8898e89 + 2de34c7 commit b802ab8
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 65 deletions.
154 changes: 89 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,72 +10,96 @@ A collection of common functions but with better performance, less allocations a

## Benchmarks

Environment:
goos: darwin
goarch: amd64
pkg: github.com/gofiber/utils
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz

```go
// go test -benchmem -run=^$ -bench=Benchmark_ -count=2

Benchmark_ToLowerBytes/fiber-16 51138252 22.61 ns/op 0 B/op 0 allocs/op
Benchmark_ToLowerBytes/fiber-16 52126545 22.63 ns/op 0 B/op 0 allocs/op
Benchmark_ToLowerBytes/default-16 16114736 72.76 ns/op 80 B/op 1 allocs/op
Benchmark_ToLowerBytes/default-16 16651540 73.85 ns/op 80 B/op 1 allocs/op

Benchmark_ToUpperBytes/fiber-16 52127224 22.62 ns/op 0 B/op 0 allocs/op
Benchmark_ToUpperBytes/fiber-16 54283167 22.86 ns/op 0 B/op 0 allocs/op
Benchmark_ToUpperBytes/default-16 14060098 84.12 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpperBytes/default-16 14183122 84.51 ns/op 80 B/op 1 allocs/op

Benchmark_EqualFoldBytes/fiber-16 29240264 41.22 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/fiber-16 28535826 40.84 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/default-16 7929867 150.2 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/default-16 7935478 149.7 ns/op 0 B/op 0 allocs/op

Benchmark_EqualFold/fiber-16 35442768 34.25 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/fiber-16 35946870 34.96 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/default-16 8942130 133.5 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/default-16 8977231 134.3 ns/op 0 B/op 0 allocs/op

Benchmark_UUID/fiber-16 30726213 40.57 ns/op 48 B/op 1 allocs/op
Benchmark_UUID/fiber-16 26539394 40.25 ns/op 48 B/op 1 allocs/op
Benchmark_UUID/default-16 4737199 247.5 ns/op 168 B/op 6 allocs/op
Benchmark_UUID/default-16 4603738 250.8 ns/op 168 B/op 6 allocs/op

Benchmark_ConvertToBytes/fiber-16 62450884 19.41 ns/op 0 B/op 0 allocs/op
Benchmark_ConvertToBytes/fiber-16 52123602 19.53 ns/op 0 B/op 0 allocs/op

Benchmark_UnsafeString/unsafe-16 1000000000 0.4496 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeString/unsafe-16 1000000000 0.4488 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeString/default-16 79925935 13.99 ns/op 16 B/op 1 allocs/op
Benchmark_UnsafeString/default-16 85637211 14.35 ns/op 16 B/op 1 allocs/op

Benchmark_UnsafeBytes/unsafe-16 540970148 2.214 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeBytes/unsafe-16 543356940 2.212 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeBytes/default-16 68896224 17.19 ns/op 16 B/op 1 allocs/op
Benchmark_UnsafeBytes/default-16 70560426 17.05 ns/op 16 B/op 1 allocs/op

Benchmark_ToString-16 29504036 39.57 ns/op 40 B/op 2 allocs/op
Benchmark_ToString-16 30738334 38.89 ns/op 40 B/op 2 allocs/op

Benchmark_GetMIME/fiber-16 28207086 41.84 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/fiber-16 28165773 41.83 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/default-16 12583132 94.04 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/default-16 12829614 93.50 ns/op 0 B/op 0 allocs/op

Benchmark_ParseVendorSpecificContentType/vendorContentType-16 30267411 38.72 ns/op 16 B/op 1 allocs/op
Benchmark_ParseVendorSpecificContentType/vendorContentType-16 28543563 38.60 ns/op 16 B/op 1 allocs/op
Benchmark_ParseVendorSpecificContentType/defaultContentType-16 249869286 4.830 ns/op 0 B/op 0 allocs/op
Benchmark_ParseVendorSpecificContentType/defaultContentType-16 248999592 4.805 ns/op 0 B/op 0 allocs/op

Benchmark_StatusMessage/fiber-16 1000000000 0.6744 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/fiber-16 1000000000 0.6788 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/default-16 446818872 2.664 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/default-16 447009616 2.661 ns/op 0 B/op 0 allocs/op

Benchmark_ToUpper/fiber-16 20480331 56.50 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/fiber-16 21541200 56.65 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/default-16 8433409 141.2 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/default-16 8473737 141.1 ns/op 80 B/op 1 allocs/op

Benchmark_ToLower/fiber-16 27248326 44.68 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/fiber-16 26918443 44.70 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/default-16 8447336 141.9 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/default-16 8423156 140.6 ns/op 80 B/op 1 allocs/op
Benchmark_ToLowerBytes/fiber-12 29715831 36.44 ns/op 0 B/op 0 allocs/op
Benchmark_ToLowerBytes/fiber-12 33316479 36.28 ns/op 0 B/op 0 allocs/op
Benchmark_ToLowerBytes/default-12 11894427 96.98 ns/op 80 B/op 1 allocs/op
Benchmark_ToLowerBytes/default-12 12217050 97.43 ns/op 80 B/op 1 allocs/op

Benchmark_ToUpperBytes/fiber-12 22042162 46.92 ns/op 0 B/op 0 allocs/op
Benchmark_ToUpperBytes/fiber-12 25859680 46.43 ns/op 0 B/op 0 allocs/op
Benchmark_ToUpperBytes/default-12 10015346 117.2 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpperBytes/default-12 10185375 117.8 ns/op 80 B/op 1 allocs/op

Benchmark_EqualFoldBytes/fiber-12 22944849 47.14 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/fiber-12 26006342 46.82 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/default-12 5222006 222.5 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFoldBytes/default-12 5349398 223.2 ns/op 0 B/op 0 allocs/op

Benchmark_EqualFold/fiber-12 24761037 48.63 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/fiber-12 24159073 48.63 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/default-12 6322188 191.5 ns/op 0 B/op 0 allocs/op
Benchmark_EqualFold/default-12 6319070 193.5 ns/op 0 B/op 0 allocs/op

Benchmark_UUID/fiber-12 22061482 49.13 ns/op 48 B/op 1 allocs/op
Benchmark_UUID/fiber-12 24123198 48.40 ns/op 48 B/op 1 allocs/op
Benchmark_UUID/default-12 3581961 336.9 ns/op 168 B/op 6 allocs/op
Benchmark_UUID/default-12 3465946 344.8 ns/op 168 B/op 6 allocs/op

Benchmark_ConvertToBytes/fiber-12 53392819 23.19 ns/op 0 B/op 0 allocs/op
Benchmark_ConvertToBytes/fiber-12 51117225 23.32 ns/op 0 B/op 0 allocs/op

Benchmark_UnsafeString/unsafe-12 1000000000 0.5672 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeString/unsafe-12 1000000000 0.5683 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeString/default-12 64000897 18.45 ns/op 16 B/op 1 allocs/op
Benchmark_UnsafeString/default-12 64138909 18.13 ns/op 16 B/op 1 allocs/op

Benchmark_UnsafeBytes/unsafe-12 474777096 2.539 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeBytes/unsafe-12 469340781 2.535 ns/op 0 B/op 0 allocs/op
Benchmark_UnsafeBytes/default-12 53125656 22.15 ns/op 16 B/op 1 allocs/op
Benchmark_UnsafeBytes/default-12 52615048 22.33 ns/op 16 B/op 1 allocs/op

Benchmark_ToString-12 22981430 51.72 ns/op 40 B/op 2 allocs/op
Benchmark_ToString-12 22956476 52.93 ns/op 40 B/op 2 allocs/op

Benchmark_GetMIME/fiber-12 15782622 74.99 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/fiber-12 13992375 93.13 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/default-12 6825952 147.0 ns/op 0 B/op 0 allocs/op
Benchmark_GetMIME/default-12 9158227 132.5 ns/op 0 B/op 0 allocs/op

ParseVendorSpecificContentType
Benchmark_Parse.../vendorContentType-12 21334663 50.24 ns/op 16 B/op 1 allocs/op
Benchmark_Parse.../vendorContentType-12 23121808 51.20 ns/op 16 B/op 1 allocs/op
Benchmark_Parse.../defaultContentType-12 154423909 6.772 ns/op 0 B/op 0 allocs/op
Benchmark_Parse.../defaultContentType-12 183285117 6.662 ns/op 0 B/op 0 allocs/op

Benchmark_StatusMessage/fiber-12 1000000000 0.9796 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/fiber-12 1000000000 0.9706 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/default-12 380260562 2.989 ns/op 0 B/op 0 allocs/op
Benchmark_StatusMessage/default-12 403639642 3.124 ns/op 0 B/op 0 allocs/op

Benchmark_IsIPv4/fiber-12 53576214 21.07 ns/op 0 B/op 0 allocs/op
Benchmark_IsIPv4/fiber-12 62672907 22.04 ns/op 0 B/op 0 allocs/op
Benchmark_IsIPv4/default-12 21204613 62.23 ns/op 16 B/op 1 allocs/op
Benchmark_IsIPv4/default-12 21399847 56.61 ns/op 16 B/op 1 allocs/op

Benchmark_IsIPv6/fiber-12 16754995 72.46 ns/op 0 B/op 0 allocs/op
Benchmark_IsIPv6/fiber-12 17080897 74.31 ns/op 0 B/op 0 allocs/op
Benchmark_IsIPv6/default-12 8160195 124.5 ns/op 16 B/op 1 allocs/op
Benchmark_IsIPv6/default-12 9415326 119.8 ns/op 16 B/op 1 allocs/op

Benchmark_ToUpper/fiber-12 13175154 81.67 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/fiber-12 14285533 77.27 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/default-12 5332206 231.8 ns/op 80 B/op 1 allocs/op
Benchmark_ToUpper/default-12 5364650 236.0 ns/op 80 B/op 1 allocs/op

Benchmark_ToLower/fiber-12 12996409 80.24 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/fiber-12 16539536 69.27 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/default-12 5132185 222.5 ns/op 80 B/op 1 allocs/op
Benchmark_ToLower/default-12 5158561 225.3 ns/op 80 B/op 1 allocs/op

Benchmark_CalculateTimestamp/fiber-12 1000000000 0.2634 ns/op 0 B/op 0 allocs/op
Benchmark_CalculateTimestamp/fiber-12 1000000000 0.2935 ns/op 0 B/op 0 allocs/op
Benchmark_CalculateTimestamp/default-12 15740576 73.79 ns/op 0 B/op 0 allocs/op
Benchmark_CalculateTimestamp/default-12 15789036 71.12 ns/op 0 B/op 0 allocs/op
```

See all the benchmarks under https://gofiber.github.io/utils/
32 changes: 32 additions & 0 deletions time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package utils

import (
"sync"
"sync/atomic"
"time"
)

var (
timestampTimer sync.Once
// Timestamp please start the timer function before you use this value
// please load the value with atomic `atomic.LoadUint32(&utils.Timestamp)`
Timestamp uint32
)

// StartTimeStampUpdater starts a concurrent function which stores the timestamp to an atomic value per second,
// which is much better for performance than determining it at runtime each time
func StartTimeStampUpdater() {
timestampTimer.Do(func() {
// set initial value
atomic.StoreUint32(&Timestamp, uint32(time.Now().Unix()))
go func(sleep time.Duration) {
ticker := time.NewTicker(sleep)
defer ticker.Stop()

for t := range ticker.C {
// update timestamp
atomic.StoreUint32(&Timestamp, uint32(t.Unix()))
}
}(1 * time.Second) // duration
})
}
47 changes: 47 additions & 0 deletions time_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package utils

import (
"sync/atomic"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func checkTimeStamp(t testing.TB, expectedCurrent, actualCurrent uint32) {
// test with some buffer in front and back of the expectedCurrent time -> because of the timing on the work machine
require.Equal(t, true, actualCurrent >= expectedCurrent-1 || actualCurrent <= expectedCurrent+1)
}

func Test_TimeStampUpdater(t *testing.T) {
t.Parallel()

StartTimeStampUpdater()

now := uint32(time.Now().Unix())
checkTimeStamp(t, now, atomic.LoadUint32(&Timestamp))
// one second later
time.Sleep(1 * time.Second)
checkTimeStamp(t, now+1, atomic.LoadUint32(&Timestamp))
// two seconds later
time.Sleep(1 * time.Second)
checkTimeStamp(t, now+2, atomic.LoadUint32(&Timestamp))
}

func Benchmark_CalculateTimestamp(b *testing.B) {
StartTimeStampUpdater()

var res uint32
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = atomic.LoadUint32(&Timestamp)
}
checkTimeStamp(b, uint32(time.Now().Unix()), res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = uint32(time.Now().Unix())
}
checkTimeStamp(b, uint32(time.Now().Unix()), res)
})
}

0 comments on commit b802ab8

Please sign in to comment.