Skip to content

Commit f33c1a3

Browse files
committed
performance: Misc allocation improvements
``` │ stash.bench │ perf-allloc20251118.bench │ │ sec/op │ sec/op vs base │ CreateShortcodePlaceholders-10 54.16n ± ∞ ¹ 39.06n ± ∞ ¹ -27.87% (p=0.029 n=4) ¹ need >= 6 samples for confidence interval at level 0.95 │ stash.bench │ perf-allloc20251118.bench │ │ B/op │ B/op vs base │ CreateShortcodePlaceholders-10 52.00 ± ∞ ¹ 48.00 ± ∞ ¹ -7.69% (p=0.029 n=4) ¹ need >= 6 samples for confidence interval at level 0.95 │ stash.bench │ perf-allloc20251118.bench │ │ allocs/op │ allocs/op vs base │ CreateShortcodePlaceholders-10 2.000 ± ∞ ¹ 1.000 ± ∞ ¹ -50.00% (p=0.029 n=4) ¹ need >= 6 samples for confidence interval at level 0.95 ````
1 parent fee0957 commit f33c1a3

File tree

6 files changed

+48
-23
lines changed

6 files changed

+48
-23
lines changed

hugolib/hugo_sites.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ type HugoSites struct {
8686
// Cache for page listings.
8787
cachePages *dynacache.Partition[string, page.Pages]
8888
// Cache for content sources.
89-
cacheContentSource *dynacache.Partition[string, *resources.StaleValue[[]byte]]
89+
cacheContentSource *dynacache.Partition[uint64, *resources.StaleValue[[]byte]]
9090

9191
// Before Hugo 0.122.0 we managed all translations in a map using a translationKey
9292
// that could be overridden in front matter.

hugolib/page__content.go

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"fmt"
2020
"html/template"
2121
"io"
22-
"strconv"
2322
"strings"
2423
"sync/atomic"
2524
"unicode/utf8"
@@ -69,12 +68,6 @@ func (m *pageMetaSource) parseFrontMatter(
6968
h *HugoSites,
7069
sid uint64,
7170
) error {
72-
var sourceKey string
73-
74-
if sourceKey == "" {
75-
sourceKey = strconv.FormatUint(sid, 10)
76-
}
77-
7871
var filename string
7972
if m.f != nil {
8073
filename = m.f.Filename()
@@ -83,7 +76,6 @@ func (m *pageMetaSource) parseFrontMatter(
8376
m.pi = &contentParseInfo{
8477
h: h,
8578
sid: sid,
86-
sourceKey: sourceKey,
8779
openSource: m.openSource,
8880
shortcodeParseInfo: newShortcodeHandler(filename, h.Deps),
8981
}
@@ -163,8 +155,7 @@ func (c *cachedContent) getOrCreateScope(scope string, pco *pageContentOutput) *
163155
type contentParseInfo struct {
164156
h *HugoSites
165157

166-
sid uint64
167-
sourceKey string
158+
sid uint64
168159

169160
// The source bytes.
170161
openSource hugio.OpenReadSeekCloser
@@ -323,7 +314,7 @@ Loop:
323314
currShortcode.pos = it.Pos()
324315
currShortcode.length = iter.Current().Pos() - it.Pos()
325316
if currShortcode.placeholder == "" {
326-
currShortcode.placeholder = createShortcodePlaceholder("s", pi.sid, currShortcode.ordinal)
317+
currShortcode.placeholder = createShortcodePlaceholder("s", pi.sid, uint64(currShortcode.ordinal))
327318
}
328319

329320
if currShortcode.name != "" {
@@ -335,7 +326,7 @@ Loop:
335326
currShortcode.params = s
336327
}
337328

338-
currShortcode.placeholder = createShortcodePlaceholder("s", pi.sid, ordinal)
329+
currShortcode.placeholder = createShortcodePlaceholder("s", pi.sid, uint64(ordinal))
339330
ordinal++
340331
s.shortcodes = append(s.shortcodes, currShortcode)
341332

@@ -390,10 +381,10 @@ func (c *cachedContent) mustSource() []byte {
390381
}
391382

392383
func (pi *contentParseInfo) contentSource(s resource.StaleInfo) ([]byte, error) {
393-
key := pi.sourceKey
384+
key := pi.sid
394385
versionv := s.StaleVersion()
395386

396-
v, err := pi.h.cacheContentSource.GetOrCreate(key, func(string) (*resources.StaleValue[[]byte], error) {
387+
v, err := pi.h.cacheContentSource.GetOrCreate(key, func(uint64) (*resources.StaleValue[[]byte], error) {
397388
b, err := pi.readSourceAll()
398389
if err != nil {
399390
return nil, err
@@ -457,13 +448,13 @@ type contentPlainPlainWords struct {
457448
}
458449

459450
func (c *cachedContentScope) keyScope(ctx context.Context) string {
460-
return hugo.GetMarkupScope(ctx) + c.pco.po.f.Name
451+
return hugo.GetMarkupScope(ctx) + c.pco.po.f.Name + fmt.Sprintf("_%d", c.pi.sid)
461452
}
462453

463454
func (c *cachedContentScope) contentRendered(ctx context.Context) (contentSummary, error) {
464455
cp := c.pco
465456
ctx = tpl.Context.DependencyScope.Set(ctx, pageDependencyScopeGlobal)
466-
key := c.pi.sourceKey + "/" + c.keyScope(ctx)
457+
key := c.keyScope(ctx)
467458

468459
versionv := c.version(cp)
469460

@@ -616,7 +607,7 @@ var setGetContentCallbackInContext = contexthelpers.NewContextDispatcher[func(*p
616607

617608
func (c *cachedContentScope) contentToC(ctx context.Context) (contentTableOfContents, error) {
618609
cp := c.pco
619-
key := c.pi.sourceKey + "/" + c.keyScope(ctx)
610+
key := c.keyScope(ctx)
620611
versionv := c.version(cp)
621612

622613
v, err := c.pm.contentTableOfContents.GetOrCreate(key, func(string) (*resources.StaleValue[contentTableOfContents], error) {
@@ -737,7 +728,7 @@ func (c *cachedContent) version(cp *pageContentOutput) uint32 {
737728

738729
func (c *cachedContentScope) contentPlain(ctx context.Context) (contentPlainPlainWords, error) {
739730
cp := c.pco
740-
key := c.pi.sourceKey + "/" + c.keyScope(ctx)
731+
key := c.keyScope(ctx)
741732

742733
versionv := c.version(cp)
743734

hugolib/shortcode.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ func (scp *ShortcodeWithPage) Unwrapv() any {
192192
// Note - this value must not contain any markup syntax
193193
const shortcodePlaceholderPrefix = "HAHAHUGOSHORTCODE"
194194

195-
func createShortcodePlaceholder(sid string, id uint64, ordinal int) string {
196-
return shortcodePlaceholderPrefix + strconv.FormatUint(id, 10) + sid + strconv.Itoa(ordinal) + "HBHB"
195+
func createShortcodePlaceholder(sid string, id, ordinal uint64) string {
196+
return shortcodePlaceholderPrefix + strconv.FormatUint(id, 10) + sid + strconv.FormatUint(ordinal, 10) + "HBHB"
197197
}
198198

199199
type shortcode struct {

hugolib/shortcode_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2025 The Hugo Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package hugolib
15+
16+
import "testing"
17+
18+
func BenchmarkCreateShortcodePlaceholders(b *testing.B) {
19+
var ordinal int = 42
20+
for b.Loop() {
21+
createShortcodePlaceholder("shortcodeName", 32, uint64(ordinal))
22+
}
23+
}

hugolib/site.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ func newHugoSites(
451451
page.Pages](d.MemCache, "/pags/all",
452452
dynacache.OptionsPartition{Weight: 10, ClearWhen: dynacache.ClearOnRebuild},
453453
),
454-
cacheContentSource: dynacache.GetOrCreatePartition[string, *resources.StaleValue[[]byte]](d.MemCache, "/cont/src", dynacache.OptionsPartition{Weight: 70, ClearWhen: dynacache.ClearOnChange}),
454+
cacheContentSource: dynacache.GetOrCreatePartition[uint64, *resources.StaleValue[[]byte]](d.MemCache, "/cont/src", dynacache.OptionsPartition{Weight: 70, ClearWhen: dynacache.ClearOnChange}),
455455
translationKeyPages: maps.NewSliceCache[page.Page](),
456456
currentSite: first[0],
457457
skipRebuildForFilenames: make(map[string]bool),

hugolib/sitesmatrix/vectorstores_test.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,22 @@ func BenchmarkSets(b *testing.B) {
398398
}
399399
})
400400

401-
b.Run("HasAnyVector", func(b *testing.B) {
401+
b.Run("HasAnyVector(Sets)", func(b *testing.B) {
402402
for b.Loop() {
403403
_ = sets1.HasAnyVector(sets2)
404404
}
405405
})
406+
b.Run("HasAnyVector(Vector)", func(b *testing.B) {
407+
for b.Loop() {
408+
_ = sets1.HasAnyVector(v1)
409+
}
410+
})
411+
412+
b.Run("HasAnyVector(&Vector)", func(b *testing.B) {
413+
for b.Loop() {
414+
_ = sets1.HasAnyVector(&v1)
415+
}
416+
})
406417

407418
b.Run("FirstVector", func(b *testing.B) {
408419
for b.Loop() {

0 commit comments

Comments
 (0)