aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/pem
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2018-12-31 19:48:21 +0100
committerDaniel Martí <mvdan@mvdan.cc>2019-03-02 20:43:08 +0000
commite0ff4e6dc013ac18728743a43b6faa812737bdb2 (patch)
treed467e8f652976395a365caabd1029ce21c06b312 /src/encoding/pem
parent06c86e0fc3eec6635fce31b8cd6b988087a8f872 (diff)
downloadgo-e0ff4e6dc013ac18728743a43b6faa812737bdb2.tar.gz
go-e0ff4e6dc013ac18728743a43b6faa812737bdb2.zip
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>
Diffstat (limited to 'src/encoding/pem')
-rw-r--r--src/encoding/pem/pem.go18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/encoding/pem/pem.go b/src/encoding/pem/pem.go
index 35058c306b..a7272da5ad 100644
--- a/src/encoding/pem/pem.go
+++ b/src/encoding/pem/pem.go
@@ -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 {