Skip to content

Commit

Permalink
test: 增加benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
祝黄清 committed Nov 15, 2022
1 parent f36fb70 commit adea15d
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 30 deletions.
27 changes: 13 additions & 14 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,25 @@
## 性能测试
```shell
Benchmark Results
With Go 1.13.4 darwin/amd64 on a 2.2 GHz Intel Core i7 16GB. Like all benchmarks, take these with a grain of salt.

goos: darwin
goarch: amd64
pkg: bitbucket.org/funplus/siid/bentch
BenchmarkSIID_Mongo-12 46535821 25.4 ns/op 0 B/op 0 allocs/op
BenchmarkSIID_MySQL-12 40794764 27.4 ns/op 0 B/op 0 allocs/op
BenchmarkRand-12 92630166 12.9 ns/op 0 B/op 0 allocs/op
BenchmarkTimestamp-12 17214086 69.3 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V1-12 11488557 107 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V2-12 11898156 101 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V3-12 5220328 229 ns/op 144 B/op 4 allocs/op
BenchmarkUUID_V4-12 15463155 76.4 ns/op 16 B/op 1 allocs/op
BenchmarkUUID_V5-12 4481305 271 ns/op 176 B/op 4 allocs/op
BenchmarkSnowflake-12 4928191 244 ns/op 0 B/op 0 allocs/op
pkg: github.com/sandwich-go/siid
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkSIID_MySQL
BenchmarkSIID_MySQL-16 16460401 63.43 ns/op 0 B/op 0 allocs/op
BenchmarkRand-16 92374222 12.26 ns/op 0 B/op 0 allocs/op
BenchmarkTimestamp-16 17644713 65.97 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V1-16 12334704 97.00 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V2-16 12190599 97.27 ns/op 0 B/op 0 allocs/op
BenchmarkUUID_V3-16 5514180 216.7 ns/op 144 B/op 4 allocs/op
BenchmarkUUID_V4-16 1595637 729.5 ns/op 16 B/op 1 allocs/op
BenchmarkUUID_V5-16 4900987 249.4 ns/op 168 B/op 4 allocs/op
BenchmarkSnowflake-16 4931772 244.1 ns/op 0 B/op 0 allocs/op
PASS
ok bitbucket.org/funplus/siid/bentch 14.801s
```
- `SIID`是全局唯一的数字ID生成方案,并不是`UUID`的替代品
- `SIID`整体性能数据较`UUID V5`要快10倍左右,较`Snowflake`方案快10倍左右
- `SIID`整体性能数据较`UUID V5`要快4倍左右,较`Snowflake`方案快4倍左右

## 使用方式
```go
Expand Down
98 changes: 98 additions & 0 deletions bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package siid

import (
"context"
"github.com/bwmarrin/snowflake"
uuid "github.com/satori/go.uuid"
"math/rand"
"testing"
)

func BenchmarkSIID_MySQL(b *testing.B) {
initBenchmark()
bd := New(mysqlDriverName,
WithDevelopment(false),
WithEnableMonitor(false),
WithMaxQuantum(900000),
)
if err := bd.Prepare(context.Background()); err != nil {
b.Fatal(err)
}
e, err0 := bd.Build("test2")
if err0 != nil {
b.Fatal(err0)
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = e.Next()
}
}

func BenchmarkRand(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
rand.Int63()
}
}

func BenchmarkTimestamp(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
nowFunc().Nanosecond()
}
}

func BenchmarkUUID_V1(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
uuid.NewV1()
}
}

func BenchmarkUUID_V2(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
uuid.NewV2(128)
}
}

func BenchmarkUUID_V3(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
uuid.NewV3(uuid.NamespaceDNS, "example.com")
}
}

func BenchmarkUUID_V4(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
uuid.NewV4()
}
}

func BenchmarkUUID_V5(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
uuid.NewV5(uuid.NamespaceDNS, "example.com")
}
}

func BenchmarkSnowflake(b *testing.B) {
node, err := snowflake.NewNode(1)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
node.Generate()
}
}
19 changes: 10 additions & 9 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"github.com/sandwich-go/boost/xsync"
"github.com/sandwich-go/boost/z"
"github.com/sandwich-go/logbus/glog"
"sort"
"sync"
Expand Down Expand Up @@ -151,7 +152,7 @@ type engine struct {
n uint64 // 当前值
max uint64
quantum uint64
ts time.Time
ts z.MonoTimeDuration
critical uint64

// next
Expand Down Expand Up @@ -186,7 +187,7 @@ func (e *engine) NextN(n int) (uint64, error) {
if n <= 0 {
n = 1
}
now := nowFunc()
now := z.MonoOffset()
// lock-free swap current and next ID bucket if we really really really really really need that
e.nextMutex.Lock()
var err error
Expand All @@ -209,11 +210,11 @@ func (e *engine) Stats() Stats {
return Stats{Current: e.n, Max: e.max, RenewCount: e.renewCount.Get(), RenewErrCount: e.renewErrCount.Get()}
}

func nextQuantum(lastQuantum uint64, segmentTime time.Time, segmentDuration time.Duration, minQuantum, maxQuantum uint64) uint64 {
func nextQuantum(lastQuantum uint64, segmentTime z.MonoTimeDuration, segmentDuration time.Duration, minQuantum, maxQuantum uint64) uint64 {
nq := lastQuantum
// 第一次renew使用初始值,不进行流控
if !segmentTime.IsZero() {
duration := time.Since(segmentTime)
if segmentTime > 0 {
duration := z.MonoSince(segmentTime)
if duration < segmentDuration {
// 流量增长期
nq *= 2
Expand Down Expand Up @@ -251,8 +252,8 @@ func retry(fn func(attempt int) (retry bool, err error)) error {
return err
}

func (e *engine) preRenew() (quantum uint64, begin time.Time) {
begin = nowFunc()
func (e *engine) preRenew() (quantum uint64, begin z.MonoTimeDuration) {
begin = z.MonoOffset()
quantum = nextQuantum(e.quantum, e.ts,
e.builder.visitor.GetSegmentDuration(),
e.builder.visitor.GetMinQuantum(),
Expand All @@ -261,7 +262,7 @@ func (e *engine) preRenew() (quantum uint64, begin time.Time) {
return
}

func (e *engine) postRenew(quantum uint64, begin time.Time, err error) {
func (e *engine) postRenew(quantum uint64, begin z.MonoTimeDuration, err error) {
e.renewReport(quantum, begin, err)
}

Expand Down Expand Up @@ -313,7 +314,7 @@ func (e *engine) nextOne() (uint64, error) {
e.quantum = e.nextQuantum
e.useNewQuantumReport()
// 记录号段正式投入使用的时间点
e.ts = nowFunc()
e.ts = z.MonoOffset()
// 计算renew临界值critical,renewCount不能为0,否则无法触发renew机制
renewCount := (e.max - e.n) * uint64(e.builder.visitor.GetRenewPercent()) / 100
if renewCount == 0 {
Expand Down
5 changes: 3 additions & 2 deletions engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package siid

import (
"context"
"github.com/sandwich-go/boost/z"
. "github.com/smartystreets/goconvey/convey"
"sync"
"testing"
Expand All @@ -14,9 +15,9 @@ func TestNextQuantum(t *testing.T) {
Convey("next quantum", t, func() {
var initQuantum, minQuantum, maxQuantum uint64 = 20, 10, 40
var segmentDuration = 100 * time.Millisecond
var quantum = nextQuantum(initQuantum, time.Time{}, segmentDuration, minQuantum, maxQuantum)
var quantum = nextQuantum(initQuantum, 0, segmentDuration, minQuantum, maxQuantum)
So(quantum, ShouldEqual, initQuantum)
var segmentTime = nowFunc()
var segmentTime = z.MonoOffset()
quantum = nextQuantum(quantum, segmentTime, segmentDuration, minQuantum, maxQuantum)
So(quantum, ShouldEqual, maxQuantum)
time.Sleep(segmentDuration * segmentFactor)
Expand Down
1 change: 1 addition & 0 deletions gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ func OptionsOptionDeclareWithDefault() interface{} {
"SlowQuery": time.Duration(30 * time.Millisecond), // @MethodComment(慢日志最小时长,大于该时长将输出日志)
"EnableTimeSummary": false, // @MethodComment(是否开启Next/MustNext接口的time监控,否则为统计监控)
"Development": true, // @MethodComment(是否为开发模式)
"EnableMonitor": true, // @MethodComment(是否开启监控)
}
}
13 changes: 13 additions & 0 deletions gen_options_optiongen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ module github.com/sandwich-go/siid
go 1.16

require (
github.com/bwmarrin/snowflake v0.3.0
github.com/go-sql-driver/mysql v1.6.0
github.com/prometheus/client_golang v1.14.0
github.com/sandwich-go/boost v0.1.0-alpha.13
github.com/sandwich-go/logbus v0.0.0-20221111114749-eaf446abb132
github.com/satori/go.uuid v1.2.0
github.com/smartystreets/goconvey v1.7.2
go.mongodb.org/mongo-driver v1.11.0
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
Expand Down Expand Up @@ -226,6 +228,8 @@ github.com/sandwich-go/logbus v0.0.0-20221111114749-eaf446abb132 h1:/EPUb08ibzA7
github.com/sandwich-go/logbus v0.0.0-20221111114749-eaf446abb132/go.mod h1:aA2B80lwNZtCPftyi+ZbUhVc58pH6fhNJVh4FkYxRqk=
github.com/sandwich-go/zapgen v0.0.0-20220915080429-843fca246b24 h1:KuOgs9R0jfvnloQciDboOubyg8lYO6gbN7odZmrdw+g=
github.com/sandwich-go/zapgen v0.0.0-20220915080429-843fca246b24/go.mod h1:L6T5dpY1oqAduIOpTITKQ6z2LdM2q3lEGoFsac/VISE=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shirou/gopsutil/v3 v3.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg=
github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand Down Expand Up @@ -563,6 +567,7 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
Expand Down
22 changes: 17 additions & 5 deletions reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package siid

import (
"github.com/prometheus/client_golang/prometheus"
"github.com/sandwich-go/boost/z"
"github.com/sandwich-go/logbus/glog"
"github.com/sandwich-go/logbus/monitor"
"time"
)

func getRenewStatus(err error) string {
Expand All @@ -14,7 +14,10 @@ func getRenewStatus(err error) string {
return "ok"
}

func (e *engine) renewReport(currQuantum uint64, renewBegin time.Time, err error) {
func (e *engine) renewReport(currQuantum uint64, renewBegin z.MonoTimeDuration, err error) {
if !e.builder.visitor.GetEnableMonitor() {
return
}
if err != nil {
_ = e.renewErrCount.Add(1)
glog.Error(w("renew error"), glog.Err(err), glog.String("domain", e.domain))
Expand All @@ -26,14 +29,17 @@ func (e *engine) renewReport(currQuantum uint64, renewBegin time.Time, err error
}
}
if e.builder.visitor.GetEnableTimeSummary() {
_ = monitor.Timing("siid_renew_time", time.Since(renewBegin), prometheus.Labels{"domain": e.domain, "status": getRenewStatus(err)})
_ = monitor.Timing("siid_renew_time", z.MonoSince(renewBegin), prometheus.Labels{"domain": e.domain, "status": getRenewStatus(err)})
} else {
_ = monitor.Count("siid_renew", 1, prometheus.Labels{"domain": e.domain, "status": getRenewStatus(err)})
}
}

func (e *engine) nextReport(n int, nextBegin time.Time, _ error) {
cost := time.Since(nextBegin)
func (e *engine) nextReport(n int, nextBegin z.MonoTimeDuration, _ error) {
if !e.builder.visitor.GetEnableMonitor() {
return
}
cost := z.MonoSince(nextBegin)
if e.builder.visitor.GetEnableTimeSummary() {
_ = monitor.Timing("siid_next_time", cost, prometheus.Labels{"domain": e.domain})
} else {
Expand All @@ -45,11 +51,17 @@ func (e *engine) nextReport(n int, nextBegin time.Time, _ error) {
}

func (e *engine) useNewQuantumReport() {
if !e.builder.visitor.GetEnableMonitor() {
return
}
pl := prometheus.Labels{"domain": e.domain}
_ = monitor.Gauge("siid_quantum", float64(e.quantum), pl)
_ = monitor.Gauge("siid_max", float64(e.max), pl)
}

func (e *engine) leftReport() {
if !e.builder.visitor.GetEnableMonitor() {
return
}
_ = monitor.Gauge("siid_n_left", float64(e.builder.visitor.GetLimitation()-e.n), prometheus.Labels{"domain": e.domain})
}

0 comments on commit adea15d

Please sign in to comment.