Skip to content

Commit

Permalink
perf: Decrease execution times by 1000% [DT-7499] (#277)
Browse files Browse the repository at this point in the history
* perf: Runs from ~14,000ms to ~1,400ms [DT-7499]

* perf: Runs from ~14,000ms to ~7,000ms [DT-7499]

* Change the name of the userContext function to make it clear that it will clone the context

* perf: Runs from ~14,000ms to ~4,000ms [DT-7499]

Change the name of the userContext function to make it clear that it will clone the context

perf: Runs from ~14,000ms to ~4,000ms [DT-7499]

* revert: Remove timing calls [DT-7499]

* Replace the imports

---------

Co-authored-by: Jocelyn Giroux <[email protected]>
  • Loading branch information
nicolegros and jocgir authored Nov 27, 2024
1 parent 9f9ddc6 commit 114ffda
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
48 changes: 33 additions & 15 deletions template/extra_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (t *Template) addRuntimeFuncs() {
"substitute": t.substitute,
"templateNames": t.getTemplateNames,
"templates": t.Templates,
"userContext": t.userContext,
"userContext": t.cloneUserContext,
}
t.AddFunctions(funcs, runtimeFunc, FuncOptions{
FuncHelp: runtimeFuncsHelp,
Expand All @@ -167,7 +167,7 @@ func exit(exitValue int) int { os.Exit(exitValue); return exitValue }

func (t *Template) current() string { return t.folder }

func (t *Template) userContext() interface{} {
func (t *Template) cloneUserContext() interface{} {
return t.Context().Clone().Flush(t.constantKeys...)
}

Expand Down Expand Up @@ -430,19 +430,27 @@ func (t *Template) exec(command string, args ...interface{}) (interface{}, error
}

func (t *Template) runTemplate(source string, args ...interface{}) (result, filename string, err error) {
return optimizedRunTemplate(t, false, source, args...)
}

func optimizedRunTemplate(t *Template, withClone bool, source string, args ...interface{}) (result, filename string, err error) {
if source == "" {
return
}
var out bytes.Buffer

// Keep the parent context to make it available
parentContext := t.userContext()
// Clone the current context to ensure that the sub template has a distinct set of values
t = t.GetNewContext("", false)
context := t.Context().Clone()
if context.Len() == 0 {
context.Set("CONTEXT", context)
var context collections.IDictionary

if withClone {
context = t.Context().Clone()
if context.Len() == 0 {
context.Set("CONTEXT", context)
}
context.Set("_", t.cloneUserContext())
} else {
context = collections.CreateDictionary()
}

switch len(args) {
case 1:
if arguments, err := collections.TryAsDictionary(args[0]); err == nil {
Expand All @@ -454,10 +462,6 @@ func (t *Template) runTemplate(source string, args ...interface{}) (result, file
context.Set("ARGS", args)
}

// Make the parent context available
context.Set("_", parentContext)
t.context = context

// We first try to find a template named <source>
internalTemplate := t.Lookup(source)
if internalTemplate == nil {
Expand Down Expand Up @@ -490,8 +494,21 @@ func (t *Template) runTemplate(source string, args ...interface{}) (result, file
}

// We execute the resulting template
if err = internalTemplate.Execute(&out, t.context); err != nil {
return
if withClone {
internalTemplate.Option("missingkey=default")
} else {
internalTemplate.Option("missingkey=error")
}

previous_context := t.context
t.context = context
err = internalTemplate.Execute(&out, context)
t.context = previous_context
if err != nil {
if !withClone {
TemplateLog.Debug("Running template with context cloning because:", err)
return optimizedRunTemplate(t, true, source, args...)
}
}

result = out.String()
Expand All @@ -511,6 +528,7 @@ func (t *Template) runTemplate(source string, args ...interface{}) (result, file
filename = ""
}
return

}

func (t *Template) runTemplateItf(source string, context ...interface{}) (interface{}, error) {
Expand Down
6 changes: 4 additions & 2 deletions template/extra_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ func TestRuntime(t *testing.T) {
{
name: "Get context",
content: `@define("func")
@base = 2
@-context()
@-end
@-include("func", 1, 2, 3)`,
result: `{"ARGS":[1,2,3],"_":{"base":1},"base":1}`,
@-include("func", 1, 2, 3)
@-context()`,
result: `{"ARGS":[1,2,3],"_":{"base":1},"base":2}{"base":1}`,
},
{
name: "Override parent value",
Expand Down

0 comments on commit 114ffda

Please sign in to comment.