Skip to content

Commit

Permalink
Only create LazyContentProvider for the non-rendering Site
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bep committed Jan 12, 2022
1 parent b7fcde9 commit f38fce3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 21 deletions.
33 changes: 18 additions & 15 deletions hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
10 changes: 4 additions & 6 deletions resources/page/page_lazy_contentprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()

}

0 comments on commit f38fce3

Please sign in to comment.