Skip to content

Commit

Permalink
docs: update examples/compbench for go1.21
Browse files Browse the repository at this point in the history
results on my Apple M2 Pro laptop:

$ make analysis
benchstat -filter=".name:Multiple" -col="/lib" -row="/size" -table="/concurrency" results.txt
/concurrency: single
        │    randutil     │             weightedrand             │
        │     sec/op      │   sec/op     vs base                 │
1e1          455.70n ± 0%   19.16n ± 2%   -95.80% (p=0.000 n=10)
1e2          438.20n ± 0%   32.81n ± 0%   -92.51% (p=0.000 n=10)
1e3         1179.00n ± 0%   46.00n ± 0%   -96.10% (p=0.000 n=10)
1e4         6591.00n ± 1%   60.34n ± 0%   -99.08% (p=0.000 n=10)
1e5        61188.00n ± 0%   84.83n ± 0%   -99.86% (p=0.000 n=10)
1e6        631928.5n ± 1%   112.6n ± 2%   -99.98% (p=0.000 n=10)
1e7       6402254.0n ± 1%   240.7n ± 0%  -100.00% (p=0.000 n=10)
geomean       16.84µ        63.16n        -99.62%

/concurrency: parallel
        │     randutil     │             weightedrand             │
        │      sec/op      │   sec/op     vs base                 │
1e1          589.300n ± 0%   2.026n ± 1%   -99.66% (p=0.000 n=10)
1e2          490.000n ± 0%   3.337n ± 1%   -99.32% (p=0.000 n=10)
1e3          766.500n ± 0%   4.518n ± 1%   -99.41% (p=0.000 n=10)
1e4          808.700n ± 0%   5.951n ± 2%   -99.26% (p=0.000 n=10)
1e5         6438.500n ± 1%   8.184n ± 1%   -99.87% (p=0.000 n=10)
1e6        108285.50n ± 1%   12.00n ± 1%   -99.99% (p=0.000 n=10)
1e7       2011263.00n ± 2%   28.95n ± 1%  -100.00% (p=0.000 n=10)
geomean        5.907µ        6.548n        -99.89%
  • Loading branch information
mroth committed Aug 13, 2023
1 parent c2e6731 commit 60f6145
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 65 deletions.
1 change: 1 addition & 0 deletions examples/compbench/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
results.txt
12 changes: 12 additions & 0 deletions examples/compbench/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: analysis clean
FILE=results.txt
COUNT=10

analysis: $(FILE)
benchstat -filter=".name:Multiple" -col="/lib" -row="/size" -table="/concurrency" $<

clean:
rm -f $(FILE)

$(FILE):
go test -bench=. -count=${COUNT} | tee $@
133 changes: 69 additions & 64 deletions examples/compbench/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
package compbench

import (
"fmt"
"math"
"math/rand"
"strconv"
"testing"
"time"

"github.com/jmcvetta/randutil"
"github.com/mroth/weightedrand/v2"
Expand All @@ -16,86 +16,85 @@ const BMMinChoices = 10
const BMMaxChoices = 10_000_000

func BenchmarkMultiple(b *testing.B) {
b.Run("jmc_randutil", func(b *testing.B) {
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(strconv.Itoa(n), func(b *testing.B) {
choices := convertChoices(b, mockChoices(b, n))
b.ResetTimer()
for i := 0; i < b.N; i++ {
randutil.WeightedChoice(choices)
}
})
}
})

b.Run("weightedrand", func(b *testing.B) {
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(strconv.Itoa(n), func(b *testing.B) {
choices := mockChoices(b, n)
chs, err := weightedrand.NewChooser(choices...)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
chs.Pick()
}
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(fmt.Sprintf("size=%s", fmt1eN(n)), func(b *testing.B) {
wr_choices := mockChoices(b, n)
ru_choices := convertChoices(b, wr_choices)

b.Run("concurrency=single", func(b *testing.B) {
b.Run("lib=randutil", func(b *testing.B) {
for i := 0; i < b.N; i++ {
randutil.WeightedChoice(ru_choices)
}
})

b.Run("lib=weightedrand", func(b *testing.B) {
chs, err := weightedrand.NewChooser(wr_choices...)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()

for i := 0; i < b.N; i++ {
chs.Pick()
}
})
})
}
})

b.Run("wr-parallel", func(b *testing.B) {
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(strconv.Itoa(n), func(b *testing.B) {
choices := mockChoices(b, n)
chs, err := weightedrand.NewChooser(choices...)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
rs := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
for pb.Next() {
chs.PickSource(rs)

b.Run("concurrency=parallel", func(b *testing.B) {
b.Run("lib=weightedrand", func(b *testing.B) {
chs, err := weightedrand.NewChooser(wr_choices...)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
chs.Pick()
}
})
})

b.Run("lib=randutil", func(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
randutil.WeightedChoice(ru_choices)
}
})
})
})
}
})
})
}
}

// The single usage case is an anti-pattern for the intended usage of this
// library. Might as well keep some optional benchmarks for that to illustrate
// the point.
// THE SINGLE USAGE CASE IS AN ANTI-PATTERN FOR THE INTENDED USAGE OF THIS
// LIBRARY. Provide some optional benchmarks for that to illustrate the point.
func BenchmarkSingle(b *testing.B) {
if testing.Short() {
b.Skip()
}

b.Run("jmc_randutil", func(b *testing.B) {
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(strconv.Itoa(n), func(b *testing.B) {
choices := convertChoices(b, mockChoices(b, n))
b.ResetTimer()
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(fmt.Sprintf("size=%s", fmt1eN(n)), func(b *testing.B) {
wr_choices := mockChoices(b, n)
ru_choices := convertChoices(b, wr_choices)

b.Run("lib=randutil", func(b *testing.B) {
for i := 0; i < b.N; i++ {
randutil.WeightedChoice(choices)
randutil.WeightedChoice(ru_choices)
}
})
}
})

b.Run("weightedrand", func(b *testing.B) {
for n := BMMinChoices; n <= BMMaxChoices; n *= 10 {
b.Run(strconv.Itoa(n), func(b *testing.B) {
choices := mockChoices(b, n)
b.ResetTimer()

b.Run("lib=weightedrand", func(b *testing.B) {
for i := 0; i < b.N; i++ {
chs, _ := weightedrand.NewChooser(choices...)
// never actually do this, this is not how the library is used
chs, _ := weightedrand.NewChooser(wr_choices...)
chs.Pick()
}
})
}
})
})
}
}

func mockChoices(tb testing.TB, n int) []weightedrand.Choice[rune, uint] {
Expand All @@ -118,3 +117,9 @@ func convertChoices(tb testing.TB, cs []weightedrand.Choice[rune, uint]) []randu
}
return res
}

// fmt1eN returns simplified order of magnitude scientific notation for n,
// e.g. "1e2" for 100, "1e7" for 10 million.
func fmt1eN(n int) string {
return fmt.Sprintf("1e%d", int(math.Log10(float64(n))))
}
2 changes: 1 addition & 1 deletion examples/compbench/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/mroth/weightedrand/examples/compbench

go 1.18
go 1.21

require (
github.com/jmcvetta/randutil v0.0.0-20150817122601-2bb1b664bcff
Expand Down

0 comments on commit 60f6145

Please sign in to comment.