summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorWolfy-J <[email protected]>2019-01-05 13:35:58 +0300
committerWolfy-J <[email protected]>2019-01-05 13:35:58 +0300
commit04f7ac73c477938b7390ec6ec101d0e4bcc8cd80 (patch)
tree361c8cd8a00824d0b2e5003c6a5978f630c20469 /util
parent46009112a783a1fdae95e0a061d4c8c41a1c8ff1 (diff)
second set of patches
Diffstat (limited to 'util')
-rw-r--r--util/fasttime.go36
-rw-r--r--util/fasttime_test.go46
2 files changed, 82 insertions, 0 deletions
diff --git a/util/fasttime.go b/util/fasttime.go
index a18924cb..f1a81333 100644
--- a/util/fasttime.go
+++ b/util/fasttime.go
@@ -1,5 +1,41 @@
package util
+import (
+ "sync/atomic"
+ "time"
+)
+
// FastTime provides current unix time using specified resolution with reduced number of syscalls.
type FastTime struct {
+ last int64
+ ticker *time.Ticker
+}
+
+// NewFastTime returns new time provider with given resolution.
+func NewFastTime(resolution time.Duration) *FastTime {
+ ft := &FastTime{
+ last: time.Now().UnixNano(),
+ ticker: time.NewTicker(resolution),
+ }
+
+ go ft.run()
+
+ return ft
+}
+
+// Stop ticking.
+func (ft *FastTime) Stop() {
+ ft.ticker.Stop()
+}
+
+// UnixNano returns current timestamps. Value might be delayed after current time by specified resolution.
+func (ft *FastTime) UnixNano() int64 {
+ return atomic.LoadInt64(&ft.last)
+}
+
+// consume time values over given resolution.
+func (ft *FastTime) run() {
+ for range ft.ticker.C {
+ atomic.StoreInt64(&ft.last, time.Now().UnixNano())
+ }
}
diff --git a/util/fasttime_test.go b/util/fasttime_test.go
index c7d86821..c8ff0e13 100644
--- a/util/fasttime_test.go
+++ b/util/fasttime_test.go
@@ -1 +1,47 @@
package util
+
+import (
+ "github.com/stretchr/testify/assert"
+ "testing"
+ "time"
+)
+
+func TestFTime_UnixNano(t *testing.T) {
+ ft := NewFastTime(time.Millisecond)
+ defer ft.Stop()
+
+ var d int64
+
+ d = time.Now().UnixNano() - ft.UnixNano()
+
+ assert.True(t, d >= 0)
+ assert.True(t, d <= int64(time.Millisecond*2))
+
+ time.Sleep(time.Millisecond * 100)
+ d = time.Now().UnixNano() - ft.UnixNano()
+
+ assert.True(t, d >= 0)
+ assert.True(t, d <= int64(time.Millisecond*2))
+}
+
+func Benchmark_FastTime(b *testing.B) {
+ ft := NewFastTime(time.Microsecond)
+ defer ft.Stop()
+
+ b.ReportAllocs()
+
+ for n := 0; n < b.N; n++ {
+ _ = ft.UnixNano()
+ }
+}
+
+func Benchmark_Time(b *testing.B) {
+ ft := NewFastTime(time.Microsecond)
+ defer ft.Stop()
+
+ b.ReportAllocs()
+
+ for n := 0; n < b.N; n++ {
+ _ = time.Now().UnixNano()
+ }
+}