From b9532ba225d35fe5f395025e5598eafed5525420 Mon Sep 17 00:00:00 2001 From: FishGoddess <1149062639@qq.com> Date: Wed, 7 Aug 2024 23:50:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BF=AB=E9=80=9F=E6=97=B6=E9=92=9F=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=8E=B7=E5=8F=96=20nanos=20=E7=9A=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY.md | 6 ++++++ _icons/coverage.svg | 4 ++-- extension/fastclock/fast_clock.go | 26 ++++++++++++++++-------- extension/fastclock/fast_clock_test.go | 28 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 78cd983..10feb62 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ ## ✒ 历史版本的特性介绍 (Features in old versions) +### v1.8.1 + +> 此版本发布于 2024-08-07 + +* 快速时钟增加获取 nanos 的函数 + ### v1.8.0 > 此版本发布于 2024-08-07 diff --git a/_icons/coverage.svg b/_icons/coverage.svg index 98346b3..035ad33 100644 --- a/_icons/coverage.svg +++ b/_icons/coverage.svg @@ -10,7 +10,7 @@ coverage coverage - 82% - 82% + 81% + 81% \ No newline at end of file diff --git a/extension/fastclock/fast_clock.go b/extension/fastclock/fast_clock.go index fb1f3ef..e506b45 100644 --- a/extension/fastclock/fast_clock.go +++ b/extension/fastclock/fast_clock.go @@ -28,15 +28,16 @@ import ( // In my linux server with 2 cores: // BenchmarkTimeNow-2 19150246 62.26 ns/op 0 B/op 0 allocs/op // BenchmarkFastClockNow-2 357209233 3.46 ns/op 0 B/op 0 allocs/op +// BenchmarkFastClockNowNanos-2 467461363 2.55 ns/op 0 B/op 0 allocs/op // // However, the performance of time.Now is faster enough for 99.9% situations, so we hope you never use it :) type fastClock struct { - nowNanos int64 + nanos int64 } func newClock() *fastClock { clock := &fastClock{ - nowNanos: time.Now().UnixNano(), + nanos: time.Now().UnixNano(), } go clock.start() @@ -49,17 +50,16 @@ func (fc *fastClock) start() { for { for i := 0; i < 9; i++ { time.Sleep(duration) - atomic.AddInt64(&fc.nowNanos, int64(duration)) + atomic.AddInt64(&fc.nanos, int64(duration)) } time.Sleep(duration) - atomic.StoreInt64(&fc.nowNanos, time.Now().UnixNano()) + atomic.StoreInt64(&fc.nanos, time.Now().UnixNano()) } } -func (fc *fastClock) now() time.Time { - nanos := atomic.LoadInt64(&fc.nowNanos) - return time.Unix(0, nanos) +func (fc *fastClock) Nanos() int64 { + return atomic.LoadInt64(&fc.nanos) } var ( @@ -73,5 +73,15 @@ func Now() time.Time { clock = newClock() }) - return clock.now() + nanos := NowNanos() + return time.Unix(0, nanos) +} + +// NowNanos returns the current time in nanos from fast clock. +func NowNanos() int64 { + clockOnce.Do(func() { + clock = newClock() + }) + + return clock.Nanos() } diff --git a/extension/fastclock/fast_clock_test.go b/extension/fastclock/fast_clock_test.go index 7df9f1b..3172633 100644 --- a/extension/fastclock/fast_clock_test.go +++ b/extension/fastclock/fast_clock_test.go @@ -41,6 +41,16 @@ func BenchmarkFastClockNow(b *testing.B) { } } +// go test -v -run=^$ -bench=^BenchmarkFastClockNowNanos$ -benchtime=1s +func BenchmarkFastClockNowNanos(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + NowNanos() + } +} + // go test -v -cover -count=1 -test.cpu=1 -run=^TestNow$ func TestNow(t *testing.T) { duration := 100 * time.Millisecond @@ -57,3 +67,21 @@ func TestNow(t *testing.T) { time.Sleep(time.Duration(rand.Int63n(int64(duration)))) } } + +// go test -v -cover -count=1 -test.cpu=1 -run=^TestNowNanos$ +func TestNowNanos(t *testing.T) { + duration := 100 * time.Millisecond + + for i := 0; i < 100; i++ { + gotNanos := NowNanos() + got := time.Unix(0, gotNanos) + gap := time.Since(got) + t.Logf("got: %v, gap: %v", got, gap) + + if math.Abs(float64(gap.Nanoseconds())) > float64(duration)*1.1 { + t.Errorf("now %v is wrong", got) + } + + time.Sleep(time.Duration(rand.Int63n(int64(duration)))) + } +}