From 4e42d218370f761cb1245f67abda225a308f1a00 Mon Sep 17 00:00:00 2001 From: Dennis Gursky <81270766+dennygursky@users.noreply.github.com> Date: Mon, 5 Apr 2021 05:44:27 -0700 Subject: [PATCH] Improve ModuleInstance String() performance (#28246) * Optimize (m ModuleInstance) String() Optimize (m ModuleInstance) String() to preallocate the buffer and use strings.Builder instead of bytes.Buffer This leads to a common case only doing a single allocation as opposed to a few allocations which the bytes.Buffer is doing. * adding a benchmark test Result: ``` $ go test -bench=String ./addrs -benchmem BenchmarkStringShort-12 18271692 56.52 ns/op 16 B/op 1 allocs/op BenchmarkStringLong-12 8057071 158.5 ns/op 96 B/op 1 allocs/op PASS $ git checkout main addrs/module_instance.go $ go test -bench=String ./addrs -benchmem BenchmarkStringShort-12 7690818 162.0 ns/op 80 B/op 2 allocs/op BenchmarkStringLong-12 2922117 414.1 ns/op 288 B/op 3 allocs/op ``` * Update module_instance_test.go switch spaces to tabs --- addrs/module_instance.go | 14 ++++++++++++-- addrs/module_instance_test.go | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/addrs/module_instance.go b/addrs/module_instance.go index 7a5c03a6e..396d5f6e0 100644 --- a/addrs/module_instance.go +++ b/addrs/module_instance.go @@ -1,8 +1,8 @@ package addrs import ( - "bytes" "fmt" + "strings" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" @@ -251,7 +251,17 @@ func (m ModuleInstance) Parent() ModuleInstance { // // The address of the root module has the empty string as its representation. func (m ModuleInstance) String() string { - var buf bytes.Buffer + if len(m) == 0 { + return "" + } + // Calculate minimal necessary space (no instance keys). + l := 0 + for _, step := range m { + l += len(step.Name) + } + buf := strings.Builder{} + // 8 is len(".module.") which separates entries. + buf.Grow(l + len(m)*8) sep := "" for _, step := range m { buf.WriteString(sep) diff --git a/addrs/module_instance_test.go b/addrs/module_instance_test.go index c36e9952d..2334f28ff 100644 --- a/addrs/module_instance_test.go +++ b/addrs/module_instance_test.go @@ -77,3 +77,17 @@ func TestModuleInstanceEqual_false(t *testing.T) { }) } } + +func BenchmarkStringShort(b *testing.B) { + addr, _ := ParseModuleInstanceStr(`module.foo`) + for n := 0; n < b.N; n++ { + addr.String() + } +} + +func BenchmarkStringLong(b *testing.B) { + addr, _ := ParseModuleInstanceStr(`module.southamerica-brazil-region.module.user-regional-desktops.module.user-name`) + for n := 0; n < b.N; n++ { + addr.String() + } +}