From 3d630d2d437be609879cc79aebe7672f5f955fb1 Mon Sep 17 00:00:00 2001 From: Fuchun Zhang Date: Fri, 27 Mar 2026 13:33:02 +0800 Subject: [PATCH 1/4] reuse Parser --- parser.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/parser.go b/parser.go index f9f5ce4..dc8b5c3 100644 --- a/parser.go +++ b/parser.go @@ -2,12 +2,20 @@ package fastjson import ( "fmt" - "github.com/valyala/fastjson/fastfloat" "strconv" "strings" + "sync" "unicode/utf16" + + "github.com/valyala/fastjson/fastfloat" ) +var Pool = sync.Pool{ + New: func() any { + return &Parser{} + }, +} + // Parser parses JSON. // // Parser may be re-used for subsequent parsing. @@ -43,6 +51,27 @@ func (p *Parser) Parse(s string) (*Value, error) { return v, nil } +func (p *Parser) Reset() { + p.b = p.b[:0] + p.c.reset() +} + +func (p *Parser) ParseNoCopy(s string) (*Value, error) { + s = skipWS(s) + p.b = s2b(s) + p.c.reset() + + v, tail, err := p.c.parseValue(b2s(p.b), 0) + if err != nil { + return nil, fmt.Errorf("cannot parse JSON: %s; unparsed tail: %q", err, startEndString(tail)) + } + tail = skipWS(tail) + if len(tail) > 0 { + return nil, fmt.Errorf("unexpected tail: %q", startEndString(tail)) + } + return v, nil +} + // ParseBytes parses b containing JSON. // // The returned Value is valid until the next call to Parse*. From de3d8ffe9cb990a4de27e8a617b46051ff3e931b Mon Sep 17 00:00:00 2001 From: Fuchun Zhang Date: Fri, 27 Mar 2026 14:01:41 +0800 Subject: [PATCH 2/4] remove Pool --- parser.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/parser.go b/parser.go index dc8b5c3..e7bfd19 100644 --- a/parser.go +++ b/parser.go @@ -4,18 +4,11 @@ import ( "fmt" "strconv" "strings" - "sync" "unicode/utf16" "github.com/valyala/fastjson/fastfloat" ) -var Pool = sync.Pool{ - New: func() any { - return &Parser{} - }, -} - // Parser parses JSON. // // Parser may be re-used for subsequent parsing. From 7e32f832619591553e2239ed93df3ff70d4aa097 Mon Sep 17 00:00:00 2001 From: Fuchun Zhang Date: Fri, 10 Apr 2026 10:02:43 +0800 Subject: [PATCH 3/4] skipWSSlow improve: 15.1% faster --- parser.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/parser.go b/parser.go index e7bfd19..357db49 100644 --- a/parser.go +++ b/parser.go @@ -103,12 +103,24 @@ func skipWS(s string) string { return skipWSSlow(s) } +var wsTable = func() [256]byte { + var table [256]byte + for _, c := range []byte{0x20, 0x0A, 0x09, 0x0D} { + table[c] = 1 + } + return table +}() + +func isWSBySearchTable(ch byte) bool { + return wsTable[ch] != 0 +} + func skipWSSlow(s string) string { - if len(s) == 0 || s[0] != 0x20 && s[0] != 0x0A && s[0] != 0x09 && s[0] != 0x0D { + if len(s) == 0 || !isWSBySearchTable(s[0]) { return s } for i := 1; i < len(s); i++ { - if s[i] != 0x20 && s[i] != 0x0A && s[i] != 0x09 && s[i] != 0x0D { + if !isWSBySearchTable(s[i]) { return s[i:] } } From f6ff481bed991a4c78bd564d6e78556b205c73e9 Mon Sep 17 00:00:00 2001 From: ahfuzhang Date: Fri, 10 Apr 2026 10:45:04 +0800 Subject: [PATCH 4/4] test on amd64 server --- parser.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/parser.go b/parser.go index 357db49..7b19815 100644 --- a/parser.go +++ b/parser.go @@ -103,24 +103,20 @@ func skipWS(s string) string { return skipWSSlow(s) } -var wsTable = func() [256]byte { - var table [256]byte +var wsSearchTable = func() [256]bool { + var table [256]bool for _, c := range []byte{0x20, 0x0A, 0x09, 0x0D} { - table[c] = 1 + table[c] = true } return table }() -func isWSBySearchTable(ch byte) bool { - return wsTable[ch] != 0 -} - func skipWSSlow(s string) string { - if len(s) == 0 || !isWSBySearchTable(s[0]) { + if len(s) == 0 || !wsSearchTable[s[0]] { return s } for i := 1; i < len(s); i++ { - if !isWSBySearchTable(s[i]) { + if !wsSearchTable[s[i]] { return s[i:] } }