From 36293b60e3953d04475bfe31a7c5161013fc23a7 Mon Sep 17 00:00:00 2001 From: Kirill Korotaev Date: Mon, 3 Feb 2020 23:18:02 +0300 Subject: [PATCH] Preallocate string before unescaping This reduces number of allocations in BenchmarkEJ_Unmarshal_M-8 test from 52 down to 46. Signed-off-by: Kirill Korotaev --- jlexer/lexer.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jlexer/lexer.go b/jlexer/lexer.go index 74b5bda..62fbcf9 100644 --- a/jlexer/lexer.go +++ b/jlexer/lexer.go @@ -260,6 +260,7 @@ func findStringLen(data []byte) (isValid bool, length int) { // if no escaping is needed, original string is returned, otherwise - a new one allocated func (r *Lexer) unescapeStringToken() (err error) { data := r.token.byteValue + wasEscaped := false var unescapedData []byte for { @@ -273,6 +274,12 @@ func (r *Lexer) unescapeStringToken() (err error) { r.errParse(err.Error()) return err } + + if !wasEscaped { + unescapedData = make([]byte, 0, len(r.token.byteValue)) + wasEscaped = true + } + var d [4]byte s := utf8.EncodeRune(d[:], escapedRune) unescapedData = append(unescapedData, data[:i]...) @@ -281,7 +288,7 @@ func (r *Lexer) unescapeStringToken() (err error) { data = data[i+escapedBytes:] } - if len(unescapedData) > 0 { + if wasEscaped { r.token.byteValue = append(unescapedData, data...) r.token.byteValueCloned = true }