mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
tsweb: memoize the string forms of HTTP response codes.
Saves 1-2 allocs per HTTP request after warmup, thanks to avoiding strconv and fmt. Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
parent
9343967317
commit
e1c1d47991
@ -23,6 +23,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
@ -302,15 +303,38 @@ func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if h.opts.StatusCodeCounters != nil {
|
if h.opts.StatusCodeCounters != nil {
|
||||||
key := fmt.Sprintf("%dxx", msg.Code/100)
|
h.opts.StatusCodeCounters.Add(responseCodeString(msg.Code/100), 1)
|
||||||
h.opts.StatusCodeCounters.Add(key, 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.opts.StatusCodeCountersFull != nil {
|
if h.opts.StatusCodeCountersFull != nil {
|
||||||
h.opts.StatusCodeCountersFull.Add(strconv.Itoa(msg.Code), 1)
|
h.opts.StatusCodeCountersFull.Add(responseCodeString(msg.Code), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func responseCodeString(code int) string {
|
||||||
|
if v, ok := responseCodeCache.Load(code); ok {
|
||||||
|
return v.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret string
|
||||||
|
if code < 10 {
|
||||||
|
ret = fmt.Sprintf("%dxx", code)
|
||||||
|
} else {
|
||||||
|
ret = strconv.Itoa(code)
|
||||||
|
}
|
||||||
|
responseCodeCache.Store(code, ret)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// responseCodeCache memoizes the string form of HTTP response codes,
|
||||||
|
// so that the hot request-handling codepath doesn't have to allocate
|
||||||
|
// in strconv/fmt for every request.
|
||||||
|
//
|
||||||
|
// Keys are either full HTTP response code ints (200, 404) or "family"
|
||||||
|
// ints representing entire families (e.g. 2 for 2xx codes). Values
|
||||||
|
// are the string form of that code/family.
|
||||||
|
var responseCodeCache sync.Map
|
||||||
|
|
||||||
// loggingResponseWriter wraps a ResponseWriter and record the HTTP
|
// loggingResponseWriter wraps a ResponseWriter and record the HTTP
|
||||||
// response code that gets sent, if any.
|
// response code that gets sent, if any.
|
||||||
type loggingResponseWriter struct {
|
type loggingResponseWriter struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user