From 865559ae8fcbfe1b254f5e45ea39b8d2b3f4fc81 Mon Sep 17 00:00:00 2001 From: Mateus Veloso Date: Mon, 6 Nov 2023 12:39:22 -0300 Subject: [PATCH 1/4] Optimize memory allocation in appendRune function --- types/append.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/append.go b/types/append.go index 05be2a0f..342d478b 100644 --- a/types/append.go +++ b/types/append.go @@ -160,7 +160,9 @@ func appendRune(b []byte, r rune) []byte { } l := len(b) if cap(b)-l < utf8.UTFMax { - b = append(b, make([]byte, utf8.UTFMax)...) + nb := make([]byte, l, 2*l+utf8.UTFMax) + copy(nb, b) + b = nb } n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) return b[:l+n] From c45837f5b5c98fc22b32f8ab4a06968cbf18aef6 Mon Sep 17 00:00:00 2001 From: Mateus Veloso Date: Mon, 6 Nov 2023 16:26:54 -0300 Subject: [PATCH 2/4] Add benchmark tests for appendRune function memory allocation --- types/append_test.go | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 types/append_test.go diff --git a/types/append_test.go b/types/append_test.go new file mode 100644 index 00000000..c3939157 --- /dev/null +++ b/types/append_test.go @@ -0,0 +1,56 @@ +package types + +import ( + "testing" + "unicode/utf8" +) + +func BenchmarkAppendRuneOld(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + s := make([]byte, 0, 1024) + b.StartTimer() + + for j := 0; j < 1000000; j++ { + s = appendRuneOld(s, '世') + } + } +} + +func BenchmarkAppendRuneNew(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + s := make([]byte, 0, 1024) + b.StartTimer() + + for j := 0; j < 1000000; j++ { + s = appendRuneNew(s, '世') + } + } +} + +func appendRuneOld(b []byte, r rune) []byte { + if r < utf8.RuneSelf { + return append(b, byte(r)) + } + l := len(b) + if cap(b)-l < utf8.UTFMax { + b = append(b, make([]byte, utf8.UTFMax)...) + } + n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) + return b[:l+n] +} + +func appendRuneNew(b []byte, r rune) []byte { + if r < utf8.RuneSelf { + return append(b, byte(r)) + } + l := len(b) + if cap(b)-l < utf8.UTFMax { + nb := make([]byte, l, 2*l+utf8.UTFMax) + copy(nb, b) + b = nb + } + n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) + return b[:l+n] +} From 7c42824a6fa3ffa85cfd067eeb4a21c91fdc6c0a Mon Sep 17 00:00:00 2001 From: Mateus Veloso Date: Mon, 6 Nov 2023 16:31:10 -0300 Subject: [PATCH 3/4] remove function --- types/append_test.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/types/append_test.go b/types/append_test.go index c3939157..c2c63c0d 100644 --- a/types/append_test.go +++ b/types/append_test.go @@ -24,7 +24,7 @@ func BenchmarkAppendRuneNew(b *testing.B) { b.StartTimer() for j := 0; j < 1000000; j++ { - s = appendRuneNew(s, '世') + s = appendRune(s, '世') } } } @@ -40,17 +40,3 @@ func appendRuneOld(b []byte, r rune) []byte { n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) return b[:l+n] } - -func appendRuneNew(b []byte, r rune) []byte { - if r < utf8.RuneSelf { - return append(b, byte(r)) - } - l := len(b) - if cap(b)-l < utf8.UTFMax { - nb := make([]byte, l, 2*l+utf8.UTFMax) - copy(nb, b) - b = nb - } - n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) - return b[:l+n] -} From 8e1f74a299d1123de9cd794cd71f73abbf5bdb14 Mon Sep 17 00:00:00 2001 From: Mateus Veloso Date: Tue, 7 Nov 2023 22:07:20 -0300 Subject: [PATCH 4/4] remove old --- types/append_test.go | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/types/append_test.go b/types/append_test.go index c2c63c0d..5a2df1cc 100644 --- a/types/append_test.go +++ b/types/append_test.go @@ -2,21 +2,8 @@ package types import ( "testing" - "unicode/utf8" ) -func BenchmarkAppendRuneOld(b *testing.B) { - for i := 0; i < b.N; i++ { - b.StopTimer() - s := make([]byte, 0, 1024) - b.StartTimer() - - for j := 0; j < 1000000; j++ { - s = appendRuneOld(s, '世') - } - } -} - func BenchmarkAppendRuneNew(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() @@ -28,15 +15,3 @@ func BenchmarkAppendRuneNew(b *testing.B) { } } } - -func appendRuneOld(b []byte, r rune) []byte { - if r < utf8.RuneSelf { - return append(b, byte(r)) - } - l := len(b) - if cap(b)-l < utf8.UTFMax { - b = append(b, make([]byte, utf8.UTFMax)...) - } - n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) - return b[:l+n] -}