-
Notifications
You must be signed in to change notification settings - Fork 788
feat(template): optimize and deprecate sprig functions #2052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(template): optimize and deprecate sprig functions #2052
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @thevilledev and thanks for raising this PR.
I am not a code owner of this repository, so don't have the final say at the moment. I did want to note that while this init function avoids the string concatenation overhead, this will not avoid the map regrowth cost also seen. It would be nice if we could look into this too, even if the investigation determines avoiding this is not possible.
I am also curious on your thoughts of how using a private global variable and init function might impact applications such as Nomad, which utilise consul-template to run and manage any number of templates on a single host via a single control application.
In the PR code at the moment, it would be possible to create the funcmap with a fixed/known size, as it's possible to know the size of the sprig map before creating this I believe. This would avoid unnecessary map growth work in this area.
c1b7bf7
to
19f8b23
Compare
Hey @jrasell!
Because these functions capture variables (
I think this will be a nice improvement for scenarios where templates are executed in masses. The most expensive part of the I prepared a Go benchmark for this: package main
import (
"testing"
"github.com/hashicorp/consul-template/template"
)
const benchmarkTemplateContent = `{{ sprig_uuidv4 }}`
func BenchmarkTemplateExecute(b *testing.B) {
brain := template.NewBrain()
tmplInput := &template.NewTemplateInput{
Contents: benchmarkTemplateContent,
}
tmpl, err := template.NewTemplate(tmplInput)
if err != nil {
b.Fatalf("Setup: Failed to create template: %v", err)
}
execInput := &template.ExecuteInput{
Brain: brain,
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := tmpl.Execute(execInput)
if err != nil {
b.Fatalf("Execution failed during benchmark: %v", err)
}
}
} Results with Main branch:
Proposed fix branch:
That's roughly 10% improvement on execution time and memory usage, and whopping 66% reduction in memory allocations.
Since the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your contribution @thevilledev 🙌
Added a small comment and will ask the team to review + add a deprecating note on sprig functions that HemerticTxtFuncMap
removes before cutting a new release.
19f8b23
to
9976ad1
Compare
d899c36
to
910b523
Compare
Consul Enterprise related test is fixed in #2053 - but even with the fix it fails, possibly due to an outdated license in the repository secrets. |
Pre-compute Sprig template functions during package init. Avoids repeated map allocation and string concatenation for Sprig functions on every template execution, addressing performance overhead reported in hashicorp#2031. In addition, use HermeticTxtFuncMap which only imports repeatable functions. This is primarily to avoid potentially malicious input. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
910b523
to
dbe0d4a
Compare
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 👍 Thanks a lot for the contribution. Seems like the CI is having a bit of a hard time but I'll rerun + look at it early next week to see if it's resolved prior to merging.
Pre-compute Sprig template functions during package init. Avoids repeated map allocation and string concatenation for Sprig functions on every template execution, addressing performance overhead reported in #2031.
In addition, use
HermeticTxtFuncMap
which only imports repeatable functions. This is primarily to avoid potentially malicious input. See implementation here.