tpl: Put Go's internal template funcs in Hugo's map
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 7 Jan 2020 09:23:24 +0000 (10:23 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 7 Jan 2020 12:18:19 +0000 (13:18 +0100)
```
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

tpl/internal/go_templates/htmltemplate/hugo_template.go
tpl/internal/go_templates/texttemplate/hugo_template.go
tpl/tplimpl/template_funcs.go

index 117d85e49672f4f91fe5378da88c8636cd928c01..eba54fbbf2528532aa62eb5752fddc8d7788473b 100644 (file)
@@ -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 {
index d881064e52ce8287029bb81af41d2e545eccb5d2..37fa969da92c939873b84c92247b967ec80f6e81 100644 (file)
@@ -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)
index 6be8aa8b7b458ece75d428019dd7f8298745c436..88869940d012549b82448fdc4751302662f8fc32 100644 (file)
@@ -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{