diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-01-11 17:32:58 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-01-12 07:45:53 +0100 |
commit | cdcd15b6c2abbb76fd95fbbf90365c56e82f46aa (patch) | |
tree | 511b578d75d51ee3154028468aa1912f3c4c61b1 | |
parent | 25d645f47ae0a32470d303c9478c9e0b2fff0f0e (diff) |
Only create LazyContentProvider for the non-rendering Site
Which saves a fair amound of allocations:
```
gobench --package ./hugolib --bench "SiteNew/Regular_D" --base master
```
Before:
```
name old time/op new time/op delta
SiteNew/Regular_Deep_content_tree-10 40.7ms ± 3% 41.2ms ± 1% ~ (p=0.343 n=4+4)
name old alloc/op new alloc/op delta
SiteNew/Regular_Deep_content_tree-10 27.7MB ± 0% 28.8MB ± 0% +3.76% (p=0.029 n=4+4)
name old allocs/op new allocs/op delta
SiteNew/Regular_Deep_content_tree-10 304k ± 0% 329k ± 0% +8.07% (p=0.029 n=4+4)
```
After:
```
name old time/op new time/op delta
SiteNew/Regular_Deep_content_tree-10 34.2ms ± 1% 34.7ms ± 1% ~ (p=0.114 n=4+4)
name old alloc/op new alloc/op delta
SiteNew/Regular_Deep_content_tree-10 27.7MB ± 0% 28.1MB ± 0% +1.38% (p=0.029 n=4+4)
name old allocs/op new allocs/op delta
SiteNew/Regular_Deep_content_tree-10 304k ± 0% 314k ± 0% +3.03% (p=0.029 n=4+4)
```
Updates #8919
-rw-r--r-- | hugolib/page.go | 33 | ||||
-rw-r--r-- | resources/page/page_lazy_contentprovider.go | 10 |
2 files changed, 22 insertions, 21 deletions
diff --git a/hugolib/page.go b/hugolib/page.go index 509a083e8..286d21075 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -940,20 +940,6 @@ func (p *pageState) shiftToOutputFormat(isRenderingSite bool, idx int) error { panic(fmt.Sprintf("pageOutput is nil for output idx %d", idx)) } - // We attempt to assign pageContentOutputs while preparing each site - // for rendering and before rendering each site. This lets us share - // content between page outputs to conserve resources. But if a template - // unexpectedly calls a method of a ContentProvider that is not yet - // initialized, we assign a LazyContentProvider that performs the - // initialization just in time. - p.pageOutput.ContentProvider = page.NewLazyContentProvider(func() (page.ContentProvider, error) { - cp, err := newPageContentOutput(p, p.pageOutput) - if err != nil { - return nil, err - } - return cp, nil - }) - // Reset any built paginator. This will trigger when re-rendering pages in // server mode. if isRenderingSite && p.pageOutput.paginator != nil && p.pageOutput.paginator.current != nil { @@ -985,7 +971,24 @@ func (p *pageState) shiftToOutputFormat(isRenderingSite bool, idx int) error { } } p.pageOutput.initContentProvider(cp) - p.pageOutput.cp = cp + } else { + // We attempt to assign pageContentOutputs while preparing each site + // for rendering and before rendering each site. This lets us share + // content between page outputs to conserve resources. But if a template + // unexpectedly calls a method of a ContentProvider that is not yet + // initialized, we assign a LazyContentProvider that performs the + // initialization just in time. + if lcp, ok := (p.pageOutput.ContentProvider.(*page.LazyContentProvider)); ok { + lcp.Reset() + } else { + p.pageOutput.ContentProvider = page.NewLazyContentProvider(func() (page.ContentProvider, error) { + cp, err := newPageContentOutput(p, p.pageOutput) + if err != nil { + return nil, err + } + return cp, nil + }) + } } return nil diff --git a/resources/page/page_lazy_contentprovider.go b/resources/page/page_lazy_contentprovider.go index d8d92d7cd..a513a063a 100644 --- a/resources/page/page_lazy_contentprovider.go +++ b/resources/page/page_lazy_contentprovider.go @@ -49,6 +49,10 @@ func NewLazyContentProvider(f func() (ContentProvider, error)) *LazyContentProvi return &lcp } +func (lcp *LazyContentProvider) Reset() { + lcp.init.Reset() +} + func (lcp *LazyContentProvider) Content() (interface{}, error) { lcp.init.Do() return lcp.cp.Content() @@ -67,35 +71,29 @@ func (lcp *LazyContentProvider) PlainWords() []string { func (lcp *LazyContentProvider) Summary() template.HTML { lcp.init.Do() return lcp.cp.Summary() - } func (lcp *LazyContentProvider) Truncated() bool { lcp.init.Do() return lcp.cp.Truncated() - } func (lcp *LazyContentProvider) FuzzyWordCount() int { lcp.init.Do() return lcp.cp.FuzzyWordCount() - } func (lcp *LazyContentProvider) WordCount() int { lcp.init.Do() return lcp.cp.WordCount() - } func (lcp *LazyContentProvider) ReadingTime() int { lcp.init.Do() return lcp.cp.ReadingTime() - } func (lcp *LazyContentProvider) Len() int { lcp.init.Do() return lcp.cp.Len() - } |