]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Speed up GetPage
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 23 Feb 2024 14:01:19 +0000 (15:01 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 23 Feb 2024 15:29:21 +0000 (16:29 +0100)
```
name                             old time/op    new time/op    delta
GetPage-10                          413ns ± 0%     287ns ± 1%  -30.47%  (p=0.029 n=4+4)
GetPageRegular/From_root-10         757ns ± 1%     706ns ± 1%   -6.75%  (p=0.029 n=4+4)
GetPageRegular/Page_relative-10     838ns ± 1%     786ns ± 1%   -6.16%  (p=0.029 n=4+4)

name                             old alloc/op   new alloc/op   delta
GetPage-10                           312B ± 0%       24B ± 0%  -92.31%  (p=0.029 n=4+4)
GetPageRegular/From_root-10          328B ± 0%      200B ± 0%  -39.02%  (p=0.029 n=4+4)
GetPageRegular/Page_relative-10      360B ± 0%      232B ± 0%  -35.56%  (p=0.029 n=4+4)

name                             old allocs/op  new allocs/op  delta
GetPage-10                           8.00 ± 0%      2.00 ± 0%  -75.00%  (p=0.029 n=4+4)
GetPageRegular/From_root-10          7.00 ± 0%      5.00 ± 0%  -28.57%  (p=0.029 n=4+4)
GetPageRegular/Page_relative-10      9.00 ± 0%      7.00 ± 0%  -22.22%  (p=0.029 n=4+4)
```

common/paths/pathparser.go
hugolib/pagecollections.go

index 898eee341c32b46f08413312e67740a9f109a82f..20f5ee30d7230b93f76707da2ccc0cffbda00ad2 100644 (file)
@@ -54,15 +54,27 @@ func NormalizePathStringBasic(s string) string {
 
 // ParseIdentity parses component c with path s into a StringIdentity.
 func (pp *PathParser) ParseIdentity(c, s string) identity.StringIdentity {
+       p := pp.parsePooled(c, s)
+       defer putPath(p)
+       return identity.StringIdentity(p.IdentifierBase())
+}
+
+// ParseBaseAndBaseNameNoIdentifier parses component c with path s into a base and a base name without any identifier.
+func (pp *PathParser) ParseBaseAndBaseNameNoIdentifier(c, s string) (string, string) {
+       p := pp.parsePooled(c, s)
+       defer putPath(p)
+       return p.Base(), p.BaseNameNoIdentifier()
+}
+
+func (pp *PathParser) parsePooled(c, s string) *Path {
        s = NormalizePathStringBasic(s)
        p := getPath()
        p.component = c
-       defer putPath(p)
        p, err := pp.doParse(c, s, p)
        if err != nil {
                panic(err)
        }
-       return identity.StringIdentity(p.IdentifierBase())
+       return p
 }
 
 // Parse parses component c with path s into Path using Hugo's content path rules.
@@ -259,7 +271,9 @@ type Path struct {
 
 var pathPool = &sync.Pool{
        New: func() any {
-               return &Path{}
+               p := &Path{}
+               p.reset()
+               return p
        },
 }
 
@@ -268,6 +282,11 @@ func getPath() *Path {
 }
 
 func putPath(p *Path) {
+       p.reset()
+       pathPool.Put(p)
+}
+
+func (p *Path) reset() {
        p.s = ""
        p.posContainerLow = -1
        p.posContainerHigh = -1
@@ -279,7 +298,6 @@ func putPath(p *Path) {
        p.disabled = false
        p.trimLeadingSlash = false
        p.unnormalized = nil
-       pathPool.Put(p)
 }
 
 // TrimLeadingSlash returns a copy of the Path with the leading slash removed.
index fe7c2f1e77ae0c1c1eff8e3371e688a73bfff908..5ed2a28f038429afe3f7afe4f8ae146b22bc3de3 100644 (file)
@@ -131,22 +131,21 @@ func (c *pageFinder) getContentNode(context page.Page, isReflink bool, ref strin
                return c.getContentNodeForRef(context, isReflink, true, inRef, ref)
        }
 
-       var refs []string
-
        // We are always looking for a content file and having an extension greatly simplifies the code that follows,
        // even in the case where the extension does not match this one.
        if ref == "/" {
-               refs = append(refs, "/_index"+defaultContentExt)
+               if n, err := c.getContentNodeForRef(context, isReflink, false, inRef, "/_index"+defaultContentExt); n != nil || err != nil {
+                       return n, err
+               }
        } else if strings.HasSuffix(ref, "/index") {
-               refs = append(refs, ref+"/index"+defaultContentExt)
-               refs = append(refs, ref+defaultContentExt)
+               if n, err := c.getContentNodeForRef(context, isReflink, false, inRef, ref+"/index"+defaultContentExt); n != nil || err != nil {
+                       return n, err
+               }
+               if n, err := c.getContentNodeForRef(context, isReflink, false, inRef, ref+defaultContentExt); n != nil || err != nil {
+                       return n, err
+               }
        } else {
-               refs = append(refs, ref+defaultContentExt)
-       }
-
-       for _, ref := range refs {
-               n, err := c.getContentNodeForRef(context, isReflink, false, inRef, ref)
-               if n != nil || err != nil {
+               if n, err := c.getContentNodeForRef(context, isReflink, false, inRef, ref+defaultContentExt); n != nil || err != nil {
                        return n, err
                }
        }
@@ -175,7 +174,7 @@ func (c *pageFinder) getContentNodeForRef(context page.Page, isReflink, hadExten
 
                rel := path.Join(baseDir, ref)
 
-               relPath := contentPathParser.Parse(files.ComponentFolderContent, rel)
+               relPath, _ := contentPathParser.ParseBaseAndBaseNameNoIdentifier(files.ComponentFolderContent, rel)
 
                n, err := c.getContentNodeFromPath(relPath, ref)
                if n != nil || err != nil {
@@ -195,9 +194,9 @@ func (c *pageFinder) getContentNodeForRef(context page.Page, isReflink, hadExten
                return nil, nil
        }
 
-       refPath := contentPathParser.Parse(files.ComponentFolderContent, ref)
+       relPath, nameNoIdentifier := contentPathParser.ParseBaseAndBaseNameNoIdentifier(files.ComponentFolderContent, ref)
 
-       n, err := c.getContentNodeFromPath(refPath, ref)
+       n, err := c.getContentNodeFromPath(relPath, ref)
 
        if n != nil || err != nil {
                return n, err
@@ -221,7 +220,7 @@ func (c *pageFinder) getContentNodeForRef(context page.Page, isReflink, hadExten
                return nil, nil
        }
 
-       n = c.pageMap.pageReverseIndex.Get(refPath.BaseNameNoIdentifier())
+       n = c.pageMap.pageReverseIndex.Get(nameNoIdentifier)
        if n == ambiguousContentNode {
                return nil, fmt.Errorf("page reference %q is ambiguous", inRef)
        }
@@ -254,9 +253,7 @@ func (c *pageFinder) getContentNodeFromRefReverseLookup(ref string, fi hugofs.Fi
        return nil, nil
 }
 
-func (c *pageFinder) getContentNodeFromPath(refPath *paths.Path, ref string) (contentNodeI, error) {
-       s := refPath.Base()
-
+func (c *pageFinder) getContentNodeFromPath(s string, ref string) (contentNodeI, error) {
        n := c.pageMap.treePages.Get(s)
        if n != nil {
                return n, nil