From f19c63de4a30f77ce9efabc425118f8642de76d6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 13 Mar 2015 23:25:17 -0700 Subject: [PATCH] helper/backend: cache route regexps (98% speedup) benchmark old ns/op new ns/op delta BenchmarkBackendRoute 49144 589 -98.80% --- helper/backend/backend.go | 17 +++++++++++------ helper/backend/backend_test.go | 9 +++++++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/helper/backend/backend.go b/helper/backend/backend.go index 6e52c8b87a..21962e7ee0 100644 --- a/helper/backend/backend.go +++ b/helper/backend/backend.go @@ -19,7 +19,8 @@ type Backend struct { // backend is in use). Paths []*Path - once sync.Once + once sync.Once + pathsRe []*regexp.Regexp } // Path is a single path that the backend responds to. @@ -52,12 +53,9 @@ type Path struct { } func (b *Backend) Route(path string) *Path { - regexps := make([]*regexp.Regexp, len(b.Paths)) - for i, p := range b.Paths { - regexps[i] = regexp.MustCompile(p.Pattern) - } + b.once.Do(b.init) - for i, re := range regexps { + for i, re := range b.pathsRe { if re.MatchString(path) { return b.Paths[i] } @@ -66,6 +64,13 @@ func (b *Backend) Route(path string) *Path { return nil } +func (b *Backend) init() { + b.pathsRe = make([]*regexp.Regexp, len(b.Paths)) + for i, p := range b.Paths { + b.pathsRe[i] = regexp.MustCompile(p.Pattern) + } +} + // FieldSchema is a basic schema to describe the format of a path field. type FieldSchema struct { Type FieldType diff --git a/helper/backend/backend_test.go b/helper/backend/backend_test.go index e921181ccb..77cf350302 100644 --- a/helper/backend/backend_test.go +++ b/helper/backend/backend_test.go @@ -19,10 +19,15 @@ func BenchmarkBackendRoute(b *testing.B) { backend.Paths = append(backend.Paths, &Path{Pattern: p}) } + // Warm any caches + backend.Route("aws/policy/foo") + + // Reset the timer since we did a lot above b.ResetTimer() + + // Run through and route. We do a sanity check of the return value for i := 0; i < b.N; i++ { - p := backend.Route("aws/policy/foo") - if p == nil { + if p := backend.Route("aws/policy/foo"); p == nil { b.Fatal("p should not be nil") } }