From dd9f39c3329e06637ba4a64b259f0fc5d8e67330 Mon Sep 17 00:00:00 2001 From: Narasimha Prasanna HN Date: Mon, 31 Oct 2022 17:34:19 +0530 Subject: [PATCH] Add benchmarks for ratelimiter --- README.md | 20 ++++++++++++++++++++ limiter_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/README.md b/README.md index 16043e2..0e21724 100644 --- a/README.md +++ b/README.md @@ -440,6 +440,26 @@ go tool cover -html=c.out -o coverage.html This will generate a file called `coverage.html`. The `coverage.html` is provided in the repo which is pre-generated. +**Benchmarks**: +Benchmarks can be executed by running: +``` +go test -bench=. +``` + +Current benchmarks are as follows: +``` +goos: linux +goarch: amd64 +pkg: github.com/Narasimha1997/ratelimiter +cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz +BenchmarkDefaultLimiter-12 11732958 85.61 ns/op +BenchmarkSyncLimiter-12 7047988 175.9 ns/op +BenchmarkConcurrentDefaultLimiter-12 7017625 163.9 ns/op +BenchmarkConcurrentSyncLimiter-12 4132976 256.3 ns/op +PASS +ok github.com/Narasimha1997/ratelimiter 46.408s +``` + #### Notes on test: The testing code produces 500 requests/sec with `2ms` precision time gap between each request. The accuracy of this `2ms` time tick generation can differ from platform to platform, even a small difference of 500 micorseconds can add up together and give more time for test to run in the end because of clock drift, as a result the error offset +/- 3 might not always work. ### Contributing diff --git a/limiter_test.go b/limiter_test.go index 7345910..c9fe4b4 100644 --- a/limiter_test.go +++ b/limiter_test.go @@ -307,3 +307,51 @@ func TestSyncLimiterCleanup(t *testing.T) { t.Fatalf("Calling ShouldAllow() on inactive limiter did not throw any errors.") } } + +func BenchmarkDefaultLimiter(b *testing.B) { + limiter := NewDefaultLimiter(100, 1*time.Second) + + for i := 0; i < b.N; i++ { + _, err := limiter.ShouldAllow(1) + if err != nil { + b.Fatalf("Error when calling ShouldAllow() on active limiter, Error: %v", err) + } + } +} + +func BenchmarkSyncLimiter(b *testing.B) { + limiter := NewSyncLimiter(100, 1*time.Second) + + for i := 0; i < b.N; i++ { + _, err := limiter.ShouldAllow(1) + if err != nil { + b.Fatalf("Error when calling ShouldAllow() on active limiter, Error: %v", err) + } + } +} + +func BenchmarkConcurrentDefaultLimiter(b *testing.B) { + limiter := NewDefaultLimiter(100, 1*time.Second) + + b.RunParallel(func(p *testing.PB) { + for p.Next() { + _, err := limiter.ShouldAllow(1) + if err != nil { + b.Fatalf("Error when calling ShouldAllow() on active limiter, Error: %v", err) + } + } + }) +} + +func BenchmarkConcurrentSyncLimiter(b *testing.B) { + limiter := NewSyncLimiter(100, 1*time.Second) + + b.RunParallel(func(p *testing.PB) { + for p.Next() { + _, err := limiter.ShouldAllow(1) + if err != nil { + b.Fatalf("Error when calling ShouldAllow() on active limiter, Error: %v", err) + } + } + }) +}