diff --git a/scanner.go b/scanner.go index 96cdaf0..c559ba1 100644 --- a/scanner.go +++ b/scanner.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "strconv" - "strings" "unicode" ) @@ -393,9 +392,11 @@ func (s *Scanner) ScanString() (any, error) { return nil, err } - var builder strings.Builder - builder.Grow(64) // Preallocate with reasonable capacity + // Reset buffer while preserving capacity + s.buffer = s.buffer[:0] + // Avoid strings.Builder as it creates a new array internally + // and instead use our rune buffer directly for { r, _, err := s.ReadRune() if err != nil { @@ -414,23 +415,23 @@ func (s *Scanner) ScanString() (any, error) { } switch escaped { case '"': - builder.WriteRune('"') + s.buffer = append(s.buffer, '"') case '\\': - builder.WriteRune('\\') + s.buffer = append(s.buffer, '\\') case 'n': - builder.WriteRune('\n') + s.buffer = append(s.buffer, '\n') case 't': - builder.WriteRune('\t') + s.buffer = append(s.buffer, '\t') default: - builder.WriteRune('\\') - builder.WriteRune(escaped) + s.buffer = append(s.buffer, '\\', escaped) } } else { - builder.WriteRune(r) + s.buffer = append(s.buffer, r) } } - return builder.String(), nil + // Convert rune slice to string once at the end + return string(s.buffer), nil } // ConvertValue converts string values to their appropriate types