hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 1cf235412f98b42aefe368e99a0e9e95bae6eef7
parent df6e9efd8f345707932231ea23dc8713afb5b026
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Tue,  7 Jan 2020 10:23:24 +0100

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

Diffstat:
Mtpl/internal/go_templates/htmltemplate/hugo_template.go | 3+++
Mtpl/internal/go_templates/texttemplate/hugo_template.go | 3+++
Mtpl/tplimpl/template_funcs.go | 20+++++++++++++++++++-
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/tpl/internal/go_templates/htmltemplate/hugo_template.go b/tpl/internal/go_templates/htmltemplate/hugo_template.go
@@ -24,6 +24,9 @@ package is auto generated.
 
 */
 
+// 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 {
diff --git a/tpl/internal/go_templates/texttemplate/hugo_template.go b/tpl/internal/go_templates/texttemplate/hugo_template.go
@@ -29,6 +29,9 @@ package is auto generated.
 
 */
 
+// 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)
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
@@ -108,7 +108,25 @@ func newTemplateExecuter(d *deps.Deps) (texttemplate.Executer, map[string]reflec
 	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{