]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
page: Add some concurrency to the building of the related page index
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 22 Feb 2023 17:37:46 +0000 (18:37 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 22 Feb 2023 19:37:41 +0000 (20:37 +0100)
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

resources/page/pages_related.go

index 74bb1713ef3bd8fd9ead6f9e05aa79cf5a421b30..3378eb160f5d1a275e137d27dbd874748d991f9a 100644 (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
        }