page: Add some concurrency to the building of the related page index

But only in the case where we know that we will need to access the Page fragments/tableofcontents.

In normal situations this will spread naturally across the CPU cores, but not in the situation where
`site.RegularPages.Related` gets called as part of e.g. the single template.

```bash
name            old time/op    new time/op    delta
RelatedSite-10    18.0ms ± 2%    11.9ms ± 1%  -34.17%  (p=0.029 n=4+4)

name            old alloc/op   new alloc/op   delta
RelatedSite-10    38.6MB ± 0%    38.6MB ± 0%     ~     (p=0.114 n=4+4)

name            old allocs/op  new allocs/op  delta
RelatedSite-10      117k ± 0%      117k ± 0%   +0.23%  (p=0.029 n=4+4)
```

See #10711
This commit is contained in:
Bjørn Erik Pedersen 2023-02-22 18:37:46 +01:00
parent 4346987faf
commit fa2d7adf10

View file

@ -18,7 +18,9 @@ import (
"fmt"
"sync"
"github.com/gohugoio/hugo/common/para"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/related"
"github.com/mitchellh/mapstructure"
"github.com/spf13/cast"
@ -163,10 +165,12 @@ type RelatedDocsHandler struct {
postingLists []*cachedPostingList
mu sync.RWMutex
workers *para.Workers
}
func NewRelatedDocsHandler(cfg related.Config) *RelatedDocsHandler {
return &RelatedDocsHandler{cfg: cfg}
return &RelatedDocsHandler{cfg: cfg, workers: para.New(config.GetNumWorkerMultiplier())}
}
func (s *RelatedDocsHandler) Clone() *RelatedDocsHandler {
@ -194,6 +198,30 @@ func (s *RelatedDocsHandler) getOrCreateIndex(ctx context.Context, p Pages) (*re
s.mu.Lock()
defer s.mu.Unlock()
for _, c := range s.cfg.Indices {
if c.Type == related.TypeFragments {
// This will trigger building the Pages' fragment map.
g, _ := s.workers.Start(ctx)
for _, page := range p {
fp, ok := page.(related.FragmentProvider)
if !ok {
continue
}
g.Run(func() error {
fp.Fragments(ctx)
return nil
})
}
if err := g.Wait(); err != nil {
return nil, err
}
break
}
}
if cachedIndex := s.getIndex(p); cachedIndex != nil {
return cachedIndex, nil
}