From 6bce2e9d41e7e39b6655fdfadff658e2c1b5315d Mon Sep 17 00:00:00 2001 From: Sergey Grebenshchikov Date: Wed, 6 Dec 2023 12:18:10 +0100 Subject: [PATCH] add benchmarks --- README.md | 27 +++++++++++++++++++++ piecewiselinear_test.go | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/README.md b/README.md index 6c1e741..0b9ad89 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ A tiny library for linear interpolation. `O(log(N))` per evaluation for `N` cont import "github.com/sgreben/piecewiselinear" ``` +- [Get it](#get-it) +- [Use it](#use-it) +- [Benchmarks](#benchmarks) + + ## Get it ```sh @@ -35,3 +40,25 @@ func main() { // 0 0.5 1 0.5 0 0 0 } ``` + +## Benchmarks + +On an Apple M1 Pro: + +- **6ns** per evaluation (`.At(x)`) for 10 control points +- **320ns** per evaluation for 10 million control points. + +``` +goos: darwin +goarch: arm64 +pkg: github.com/sgreben/piecewiselinear +BenchmarkAt4-10 217302646 5.461 ns/op 0 B/op 0 allocs/op +BenchmarkAt8-10 197175420 6.048 ns/op 0 B/op 0 allocs/op +BenchmarkAt10-10 188384818 6.283 ns/op 0 B/op 0 allocs/op +BenchmarkAt100-10 138276301 9.086 ns/op 0 B/op 0 allocs/op +BenchmarkAt1k-10 41258203 25.18 ns/op 0 B/op 0 allocs/op +BenchmarkAt10k-10 16852758 69.99 ns/op 0 B/op 0 allocs/op +BenchmarkAt100k-10 11745384 100.5 ns/op 0 B/op 0 allocs/op +BenchmarkAt1M-10 8501438 143.0 ns/op 0 B/op 0 allocs/op +BenchmarkAt10M-10 3659188 319.5 ns/op 0 B/op 0 allocs/op +``` diff --git a/piecewiselinear_test.go b/piecewiselinear_test.go index 01dbcbc..9498aa6 100644 --- a/piecewiselinear_test.go +++ b/piecewiselinear_test.go @@ -2,6 +2,7 @@ package piecewiselinear import ( "fmt" + "math/rand" "testing" ) @@ -324,3 +325,56 @@ func TestFunction_IsInterpolatedAt(t *testing.T) { }) } } + +func benchmarkWithKPoints(b *testing.B, k int) { + var f Function + f.Y = make([]float64, k) + for i := range f.Y { + f.Y[i] = rand.Float64() + } + f.X = Span(0, 1, len(f.Y)) + xs := make([]float64, len(f.X)) + for i := range f.X { + xs[i] = rand.Float64() + } + b.ResetTimer() + for n := 0; n < b.N; n++ { + _ = f.At(xs[n%len(f.X)]) + } +} + +func BenchmarkAt4(b *testing.B) { + benchmarkWithKPoints(b, 4) +} + +func BenchmarkAt8(b *testing.B) { + benchmarkWithKPoints(b, 8) +} + +func BenchmarkAt10(b *testing.B) { + benchmarkWithKPoints(b, 10) +} + +func BenchmarkAt100(b *testing.B) { + benchmarkWithKPoints(b, 100) +} + +func BenchmarkAt1k(b *testing.B) { + benchmarkWithKPoints(b, 1_000) +} + +func BenchmarkAt10k(b *testing.B) { + benchmarkWithKPoints(b, 10_000) +} + +func BenchmarkAt100k(b *testing.B) { + benchmarkWithKPoints(b, 100_000) +} + +func BenchmarkAt1M(b *testing.B) { + benchmarkWithKPoints(b, 1_000_000) +} + +func BenchmarkAt10M(b *testing.B) { + benchmarkWithKPoints(b, 10_000_000) +}