Don't use bytes.Buffer when not necessary (#549)

When parsing strings, they can be referenced directly from the document
when they don't contain escaped characters. This avoids paying to cost
of allocating (and sometimes growing) the bytes buffer unecessarily.
This commit is contained in:
Thomas Pelletier
2021-06-01 09:51:59 -04:00
committed by GitHub
parent b202375414
commit b0d6c62255
+30 -3
View File
@@ -511,8 +511,6 @@ func (p *parser) parseMultilineBasicString(b []byte) ([]byte, []byte, error) {
return nil, nil, err return nil, nil, err
} }
var builder bytes.Buffer
i := 3 i := 3
// skip the immediate new line // skip the immediate new line
@@ -522,6 +520,21 @@ func (p *parser) parseMultilineBasicString(b []byte) ([]byte, []byte, error) {
i += 2 i += 2
} }
// fast path
startIdx := i
endIdx := len(token) - len(`"""`)
for ; i < endIdx; i++ {
if token[i] == '\\' {
break
}
}
if i == endIdx {
return token[startIdx:endIdx], rest, nil
}
var builder bytes.Buffer
builder.Write(token[startIdx:i])
// The scanner ensures that the token starts and ends with quotes and that // The scanner ensures that the token starts and ends with quotes and that
// escapes are balanced. // escapes are balanced.
for ; i < len(token)-3; i++ { for ; i < len(token)-3; i++ {
@@ -673,11 +686,25 @@ func (p *parser) parseBasicString(b []byte) ([]byte, []byte, error) {
return nil, nil, err return nil, nil, err
} }
// fast path
i := len(`"`)
startIdx := i
endIdx := len(token) - len(`"`)
for ; i < endIdx; i++ {
if token[i] == '\\' {
break
}
}
if i == endIdx {
return token[startIdx:endIdx], rest, nil
}
var builder bytes.Buffer var builder bytes.Buffer
builder.Write(token[startIdx:i])
// The scanner ensures that the token starts and ends with quotes and that // The scanner ensures that the token starts and ends with quotes and that
// escapes are balanced. // escapes are balanced.
for i := 1; i < len(token)-1; i++ { for ; i < len(token)-1; i++ {
c := token[i] c := token[i]
if c == '\\' { if c == '\\' {
i++ i++