Skip to content

Commit b9532ba

Browse files
committed
快速时钟增加获取 nanos 的函数
1 parent 2ed3cc8 commit b9532ba

File tree

4 files changed

+54
-10
lines changed

4 files changed

+54
-10
lines changed

HISTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## ✒ 历史版本的特性介绍 (Features in old versions)
22

3+
### v1.8.1
4+
5+
> 此版本发布于 2024-08-07
6+
7+
* 快速时钟增加获取 nanos 的函数
8+
39
### v1.8.0
410

511
> 此版本发布于 2024-08-07

_icons/coverage.svg

Lines changed: 2 additions & 2 deletions
Loading

extension/fastclock/fast_clock.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ import (
2828
// In my linux server with 2 cores:
2929
// BenchmarkTimeNow-2 19150246 62.26 ns/op 0 B/op 0 allocs/op
3030
// BenchmarkFastClockNow-2 357209233 3.46 ns/op 0 B/op 0 allocs/op
31+
// BenchmarkFastClockNowNanos-2 467461363 2.55 ns/op 0 B/op 0 allocs/op
3132
//
3233
// However, the performance of time.Now is faster enough for 99.9% situations, so we hope you never use it :)
3334
type fastClock struct {
34-
nowNanos int64
35+
nanos int64
3536
}
3637

3738
func newClock() *fastClock {
3839
clock := &fastClock{
39-
nowNanos: time.Now().UnixNano(),
40+
nanos: time.Now().UnixNano(),
4041
}
4142

4243
go clock.start()
@@ -49,17 +50,16 @@ func (fc *fastClock) start() {
4950
for {
5051
for i := 0; i < 9; i++ {
5152
time.Sleep(duration)
52-
atomic.AddInt64(&fc.nowNanos, int64(duration))
53+
atomic.AddInt64(&fc.nanos, int64(duration))
5354
}
5455

5556
time.Sleep(duration)
56-
atomic.StoreInt64(&fc.nowNanos, time.Now().UnixNano())
57+
atomic.StoreInt64(&fc.nanos, time.Now().UnixNano())
5758
}
5859
}
5960

60-
func (fc *fastClock) now() time.Time {
61-
nanos := atomic.LoadInt64(&fc.nowNanos)
62-
return time.Unix(0, nanos)
61+
func (fc *fastClock) Nanos() int64 {
62+
return atomic.LoadInt64(&fc.nanos)
6363
}
6464

6565
var (
@@ -73,5 +73,15 @@ func Now() time.Time {
7373
clock = newClock()
7474
})
7575

76-
return clock.now()
76+
nanos := NowNanos()
77+
return time.Unix(0, nanos)
78+
}
79+
80+
// NowNanos returns the current time in nanos from fast clock.
81+
func NowNanos() int64 {
82+
clockOnce.Do(func() {
83+
clock = newClock()
84+
})
85+
86+
return clock.Nanos()
7787
}

extension/fastclock/fast_clock_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ func BenchmarkFastClockNow(b *testing.B) {
4141
}
4242
}
4343

44+
// go test -v -run=^$ -bench=^BenchmarkFastClockNowNanos$ -benchtime=1s
45+
func BenchmarkFastClockNowNanos(b *testing.B) {
46+
b.ReportAllocs()
47+
b.ResetTimer()
48+
49+
for i := 0; i < b.N; i++ {
50+
NowNanos()
51+
}
52+
}
53+
4454
// go test -v -cover -count=1 -test.cpu=1 -run=^TestNow$
4555
func TestNow(t *testing.T) {
4656
duration := 100 * time.Millisecond
@@ -57,3 +67,21 @@ func TestNow(t *testing.T) {
5767
time.Sleep(time.Duration(rand.Int63n(int64(duration))))
5868
}
5969
}
70+
71+
// go test -v -cover -count=1 -test.cpu=1 -run=^TestNowNanos$
72+
func TestNowNanos(t *testing.T) {
73+
duration := 100 * time.Millisecond
74+
75+
for i := 0; i < 100; i++ {
76+
gotNanos := NowNanos()
77+
got := time.Unix(0, gotNanos)
78+
gap := time.Since(got)
79+
t.Logf("got: %v, gap: %v", got, gap)
80+
81+
if math.Abs(float64(gap.Nanoseconds())) > float64(duration)*1.1 {
82+
t.Errorf("now %v is wrong", got)
83+
}
84+
85+
time.Sleep(time.Duration(rand.Int63n(int64(duration))))
86+
}
87+
}

0 commit comments

Comments
 (0)