mirror of
https://github.com/golang/go
synced 2024-11-16 22:14:45 -07:00
encoding/pem: skip whitespace work on most inputs
encoding/base64 already skips \r and \n when decoding, so this package must only deal with spaces and tabs. Those aren't nearly as common, so we can add a fast path with bytes.ContainsAny to skip the costly alloc and filtering code. name old time/op new time/op delta Decode-8 279µs ± 0% 259µs ± 1% -7.07% (p=0.002 n=6+6) name old speed new speed delta Decode-8 319MB/s ± 0% 343MB/s ± 1% +7.61% (p=0.002 n=6+6) name old alloc/op new alloc/op delta Decode-8 164kB ± 0% 74kB ± 0% -54.90% (p=0.002 n=6+6) name old allocs/op new allocs/op delta Decode-8 12.0 ± 0% 11.0 ± 0% -8.33% (p=0.002 n=6+6) Change-Id: Idfca8700c52f46eb70a4a7e0d2db3bf0124e4699 Reviewed-on: https://go-review.googlesource.com/c/155964 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
06c86e0fc3
commit
e0ff4e6dc0
@ -50,14 +50,22 @@ func getLine(data []byte) (line, rest []byte) {
|
||||
return bytes.TrimRight(data[0:i], " \t"), data[j:]
|
||||
}
|
||||
|
||||
// removeWhitespace returns a copy of its input with all spaces, tab and
|
||||
// newline characters removed.
|
||||
func removeWhitespace(data []byte) []byte {
|
||||
// removeSpacesAndTabs returns a copy of its input with all spaces and tabs
|
||||
// removed, if there were any. Otherwise, the input is returned unchanged.
|
||||
//
|
||||
// The base64 decoder already skips newline characters, so we don't need to
|
||||
// filter them out here.
|
||||
func removeSpacesAndTabs(data []byte) []byte {
|
||||
if !bytes.ContainsAny(data, " \t") {
|
||||
// Fast path; most base64 data within PEM contains newlines, but
|
||||
// no spaces nor tabs. Skip the extra alloc and work.
|
||||
return data
|
||||
}
|
||||
result := make([]byte, len(data))
|
||||
n := 0
|
||||
|
||||
for _, b := range data {
|
||||
if b == ' ' || b == '\t' || b == '\r' || b == '\n' {
|
||||
if b == ' ' || b == '\t' {
|
||||
continue
|
||||
}
|
||||
result[n] = b
|
||||
@ -155,7 +163,7 @@ func Decode(data []byte) (p *Block, rest []byte) {
|
||||
return decodeError(data, rest)
|
||||
}
|
||||
|
||||
base64Data := removeWhitespace(rest[:endIndex])
|
||||
base64Data := removeSpacesAndTabs(rest[:endIndex])
|
||||
p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
|
||||
n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user