summaryrefslogtreecommitdiffstats
path: root/output
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-03-18 16:46:10 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-03-27 15:43:56 +0200
commit6178238a0b069ae8ce65a23e3dd60c091de0cfef (patch)
treee4ddac46efc6324c2d79e3769eb6f5396e59745e /output
parentdf953839143c15e147d35f8908ed7f02fb62a10a (diff)
output: Speed up layout calculations
``` BenchmarkLayout-4 4883 497 -89.82% benchmark old allocs new allocs delta BenchmarkLayout-4 18 1 -94.44% benchmark old bytes new bytes delta BenchmarkLayout-4 1624 32 -98.03% ```
Diffstat (limited to 'output')
-rw-r--r--output/layout.go26
-rw-r--r--output/layout_test.go11
2 files changed, 36 insertions, 1 deletions
diff --git a/output/layout.go b/output/layout.go
index c33ce3f0c..833a6cf4a 100644
--- a/output/layout.go
+++ b/output/layout.go
@@ -17,6 +17,7 @@ import (
"fmt"
"path"
"strings"
+ "sync"
)
// LayoutDescriptor describes how a layout should be chosen. This is
@@ -32,10 +33,19 @@ type LayoutDescriptor struct {
// TODO(bep) output improve names
type LayoutHandler struct {
hasTheme bool
+
+ mu sync.RWMutex
+ cache map[layoutCacheKey][]string
+}
+
+type layoutCacheKey struct {
+ d LayoutDescriptor
+ layoutOverride string
+ f Format
}
func NewLayoutHandler(hasTheme bool) *LayoutHandler {
- return &LayoutHandler{hasTheme: hasTheme}
+ return &LayoutHandler{hasTheme: hasTheme, cache: make(map[layoutCacheKey][]string)}
}
const (
@@ -62,6 +72,16 @@ indexes/indexes.NAME.SUFFIX indexes/indexes.SUFFIX
)
func (l *LayoutHandler) For(d LayoutDescriptor, layoutOverride string, f Format) []string {
+
+ // We will get lots of requests for the same layouts, so avoid recalculations.
+ key := layoutCacheKey{d, layoutOverride, f}
+ l.mu.RLock()
+ if cacheVal, found := l.cache[key]; found {
+ l.mu.RUnlock()
+ return cacheVal
+ }
+ l.mu.RUnlock()
+
var layouts []string
layout := d.Layout
@@ -110,6 +130,10 @@ func (l *LayoutHandler) For(d LayoutDescriptor, layoutOverride string, f Format)
return layoutsWithThemeLayouts
}
+ l.mu.Lock()
+ l.cache[key] = layouts
+ l.mu.Unlock()
+
return layouts
}
diff --git a/output/layout_test.go b/output/layout_test.go
index e678197ca..aa0657a36 100644
--- a/output/layout_test.go
+++ b/output/layout_test.go
@@ -73,4 +73,15 @@ func TestLayout(t *testing.T) {
}
})
}
+
+}
+
+func BenchmarkLayout(b *testing.B) {
+ descriptor := LayoutDescriptor{Kind: "taxonomyTerm", Section: "categories"}
+ l := NewLayoutHandler(false)
+
+ for i := 0; i < b.N; i++ {
+ layouts := l.For(descriptor, "", HTMLType)
+ require.NotEmpty(b, layouts)
+ }
}