shithub: hugo

Download patch

ref: 1cf235412f98b42aefe368e99a0e9e95bae6eef7
parent: df6e9efd8f345707932231ea23dc8713afb5b026
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Tue Jan 7 05:23:24 EST 2020

tpl: Put Go's internal template funcs in Hugo's map

```
name                            old time/op    new time/op    delta
SiteNew/Many_HTML_templates-16    43.4ms ± 0%    42.7ms ± 0%  -1.71%  (p=0.016 n=4+5)

name                            old alloc/op   new alloc/op   delta
SiteNew/Many_HTML_templates-16    17.5MB ± 0%    17.5MB ± 0%    ~     (p=0.690 n=5+5)

name                            old allocs/op  new allocs/op  delta
SiteNew/Many_HTML_templates-16      247k ± 0%      247k ± 0%    ~     (p=0.310 n=5+5)
```

Fixes #6717

--- a/tpl/internal/go_templates/htmltemplate/hugo_template.go
+++ b/tpl/internal/go_templates/htmltemplate/hugo_template.go
@@ -24,6 +24,9 @@
 
 */
 
+// Export it so we can populate Hugo's func map with it, which makes it faster.
+var GoFuncs = funcMap
+
 // Prepare returns a template ready for execution.
 func (t *Template) Prepare() (*template.Template, error) {
 	if err := t.escape(); err != nil {
--- a/tpl/internal/go_templates/texttemplate/hugo_template.go
+++ b/tpl/internal/go_templates/texttemplate/hugo_template.go
@@ -29,6 +29,9 @@
 
 */
 
+// Export it so we can populate Hugo's func map with it, which makes it faster.
+var GoFuncs = builtinFuncs
+
 // Preparer prepares the template before execution.
 type Preparer interface {
 	Prepare() (*Template, error)
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -108,7 +108,25 @@
 	funcsv := make(map[string]reflect.Value)
 
 	for k, v := range funcs {
-		funcsv[k] = reflect.ValueOf(v)
+		vv := reflect.ValueOf(v)
+		funcsv[k] = vv
+	}
+
+	// Duplicate Go's internal funcs here for faster lookups.
+	for k, v := range template.GoFuncs {
+		if _, exists := funcsv[k]; !exists {
+			vv, ok := v.(reflect.Value)
+			if !ok {
+				vv = reflect.ValueOf(v)
+			}
+			funcsv[k] = vv
+		}
+	}
+
+	for k, v := range texttemplate.GoFuncs {
+		if _, exists := funcsv[k]; !exists {
+			funcsv[k] = v
+		}
 	}
 
 	exeHelper := &templateExecHelper{