hugo/hugolib/page__common.go
Bjørn Erik Pedersen 208a0de6c3 tpl: Add a partial lookup cache
````
                 │ stash.bench  │          perf-v146.bench           │
                 │    sec/op    │   sec/op     vs base               │
LookupPartial-10   248.00n ± 0%   14.75n ± 2%  -94.05% (p=0.002 n=6)

                 │ stash.bench │          perf-v146.bench          │
                 │    B/op     │   B/op     vs base                │
LookupPartial-10    48.00 ± 0%   0.00 ± 0%  -100.00% (p=0.002 n=6)

                 │ stash.bench │          perf-v146.bench           │
                 │  allocs/op  │ allocs/op   vs base                │
LookupPartial-10    3.000 ± 0%   0.000 ± 0%  -100.00% (p=0.002 n=6)
```

THe speedup above assumes reuse of the same partials over and over again, which I think is not uncommon.

This commits also adds some more lookup benchmarks. The current output of these on my MacBook looks decent:

```
BenchmarkLookupPagesLayout/Single_root-10                3031562               395.5 ns/op             0 B/op          0 allocs/op
BenchmarkLookupPagesLayout/Single_sub_folder-10          2515915               480.9 ns/op             0 B/op          0 allocs/op
BenchmarkLookupPartial-10                               84808112                14.13 ns/op            0 B/op          0 allocs/op
BenchmarkLookupShortcode/toplevelpage-10                 8111779               148.2 ns/op             0 B/op          0 allocs/op
BenchmarkLookupShortcode/nestedpage-10                   8088183               148.6 ns/op             0 B/op          0 allocs/op
```

Note that in the above the partial lookups are cahced, the others not (they are harder to cache because of the page path).

Closes #13571
2025-04-10 11:07:19 +02:00

113 lines
2.8 KiB
Go

// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hugolib
import (
"sync"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/compare"
"github.com/gohugoio/hugo/lazy"
"github.com/gohugoio/hugo/markup/converter"
"github.com/gohugoio/hugo/navigation"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/resource"
"github.com/gohugoio/hugo/source"
)
type nextPrevProvider interface {
getNextPrev() *nextPrev
}
func (p *pageCommon) getNextPrev() *nextPrev {
return p.posNextPrev
}
type nextPrevInSectionProvider interface {
getNextPrevInSection() *nextPrev
}
func (p *pageCommon) getNextPrevInSection() *nextPrev {
return p.posNextPrevSection
}
type pageCommon struct {
s *Site
m *pageMeta
sWrapped page.Site
// Lazily initialized dependencies.
init *lazy.Init
// Store holds state that survives server rebuilds.
store *maps.Scratch
// All of these represents the common parts of a page.Page
navigation.PageMenusProvider
page.AlternativeOutputFormatsProvider
page.ChildCareProvider
page.FileProvider
page.GetPageProvider
page.GitInfoProvider
page.InSectionPositioner
page.OutputFormatsProvider
page.PageMetaProvider
page.PageMetaInternalProvider
page.Positioner
page.RawContentProvider
page.RefProvider
page.ShortcodeInfoProvider
page.SitesProvider
page.TranslationsProvider
page.TreeProvider
resource.LanguageProvider
resource.ResourceDataProvider
resource.ResourceNameTitleProvider
resource.ResourceParamsProvider
resource.ResourceTypeProvider
resource.MediaTypeProvider
resource.TranslationKeyProvider
compare.Eqer
// Describes how paths and URLs for this page and its descendants
// should look like.
targetPathDescriptor page.TargetPathDescriptor
// Set if feature enabled and this is in a Git repo.
gitInfo source.GitInfo
codeowners []string
// Positional navigation
posNextPrev *nextPrev
posNextPrevSection *nextPrev
// Menus
pageMenus *pageMenus
// Internal use
page.RelatedDocsHandlerProvider
contentConverterInit sync.Once
contentConverter converter.Converter
}
func (p *pageCommon) Store() *maps.Scratch {
return p.store
}
// See issue 13016.
func (p *pageCommon) Scratch() *maps.Scratch {
return p.Store()
}