From 559f8c8456db60ede0ca6cc73db7605460ce39fd Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 14 Mar 2024 15:11:00 +0100 Subject: [PATCH] Improved performance --- Context.go | 25 ++++++++++--------------- README.md | 10 +++++----- Server.go | 7 +++++-- param.go | 7 +++++++ 4 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 param.go diff --git a/Context.go b/Context.go index fb41d12..2f97aca 100644 --- a/Context.go +++ b/Context.go @@ -7,9 +7,6 @@ import ( "unsafe" ) -// maxParams defines the maximum number of parameters per route. -const maxParams = 16 - // Context represents the interface for a request & response context. type Context interface { Bytes([]byte) error @@ -36,15 +33,13 @@ type ctx struct { request *http.Request response http.ResponseWriter server *server - paramNames [maxParams]string - paramValues [maxParams]string - paramCount int - handlerCount int + params []param + handlerCount uint8 } // Bytes responds with a raw byte slice. -func (ctx *ctx) Bytes(body []byte) error { - _, err := ctx.response.Write(body) +func (c *ctx) Bytes(body []byte) error { + _, err := c.response.Write(body) return err } @@ -66,9 +61,11 @@ func (ctx *ctx) Error(messages ...any) error { // Get retrieves a parameter. func (ctx *ctx) Get(param string) string { - for i := range ctx.paramCount { - if ctx.paramNames[i] == param { - return ctx.paramValues[i] + for i := range len(ctx.params) { + p := ctx.params[i] + + if p.Name == param { + return p.Value } } @@ -151,7 +148,5 @@ func (ctx *ctx) WriteString(body string) (int, error) { // addParameter adds a new parameter to the context. func (ctx *ctx) addParameter(name string, value string) { - ctx.paramNames[ctx.paramCount] = name - ctx.paramValues[ctx.paramCount] = value - ctx.paramCount++ + ctx.params = append(ctx.params, param{name, value}) } diff --git a/README.md b/README.md index 0ac38a0..438df79 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,11 @@ coverage: 100.0% of statements ## Benchmarks ``` -BenchmarkStatic/#00-12 33616044 33.82 ns/op 0 B/op 0 allocs/op -BenchmarkStatic/hello-12 26220148 43.75 ns/op 0 B/op 0 allocs/op -BenchmarkStatic/hello/world-12 19777713 58.89 ns/op 0 B/op 0 allocs/op -BenchmarkGitHub/gists/:id-12 20842587 56.36 ns/op 0 B/op 0 allocs/op -BenchmarkGitHub/repos/:a/:b-12 17875575 65.04 ns/op 0 B/op 0 allocs/op +BenchmarkStatic/#00-12 34975490 33.63 ns/op 0 B/op 0 allocs/op +BenchmarkStatic/hello-12 26550235 44.20 ns/op 0 B/op 0 allocs/op +BenchmarkStatic/hello/world-12 20356144 59.08 ns/op 0 B/op 0 allocs/op +BenchmarkGitHub/gists/:id-12 21693214 54.80 ns/op 0 B/op 0 allocs/op +BenchmarkGitHub/repos/:a/:b-12 18118347 65.33 ns/op 0 B/op 0 allocs/op ``` ## License diff --git a/Server.go b/Server.go index 8451bbe..64e85d2 100644 --- a/Server.go +++ b/Server.go @@ -57,7 +57,10 @@ func New() Server { } s.pool.New = func() any { - return &ctx{server: s} + return &ctx{ + server: s, + params: make([]param, 0, 8), + } } return s @@ -94,7 +97,7 @@ func (s *server) ServeHTTP(response http.ResponseWriter, request *http.Request) s.errorHandler(ctx, err) } - ctx.paramCount = 0 + ctx.params = ctx.params[:0] ctx.handlerCount = 0 s.pool.Put(ctx) } diff --git a/param.go b/param.go new file mode 100644 index 0000000..bbf8d51 --- /dev/null +++ b/param.go @@ -0,0 +1,7 @@ +package server + +// param represents a URL parameter in a route like `/user/:id`. +type param struct { + Name string + Value string +}