Commit e4c2229e authored by Ben Burkert's avatar Ben Burkert Committed by Brad Fitzpatrick

encoding/pem: eliminate allocations for newlines during encoding

benchmark           old MB/s     new MB/s     speedup
BenchmarkEncode     243.20       279.89       1.15x

benchmark           old allocs     new allocs     delta
BenchmarkEncode     1370           4              -99.71%

Change-Id: I3920bcc04b6dd89efa5da89db5594d4434426d74
Reviewed-on: https://go-review.googlesource.com/1924Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent f34964ed
...@@ -171,6 +171,8 @@ type lineBreaker struct { ...@@ -171,6 +171,8 @@ type lineBreaker struct {
out io.Writer out io.Writer
} }
var nl = []byte{'\n'}
func (l *lineBreaker) Write(b []byte) (n int, err error) { func (l *lineBreaker) Write(b []byte) (n int, err error) {
if l.used+len(b) < pemLineLength { if l.used+len(b) < pemLineLength {
copy(l.line[l.used:], b) copy(l.line[l.used:], b)
...@@ -190,7 +192,7 @@ func (l *lineBreaker) Write(b []byte) (n int, err error) { ...@@ -190,7 +192,7 @@ func (l *lineBreaker) Write(b []byte) (n int, err error) {
return return
} }
n, err = l.out.Write([]byte{'\n'}) n, err = l.out.Write(nl)
if err != nil { if err != nil {
return return
} }
...@@ -204,7 +206,7 @@ func (l *lineBreaker) Close() (err error) { ...@@ -204,7 +206,7 @@ func (l *lineBreaker) Close() (err error) {
if err != nil { if err != nil {
return return
} }
_, err = l.out.Write([]byte{'\n'}) _, err = l.out.Write(nl)
} }
return return
...@@ -248,7 +250,7 @@ func Encode(out io.Writer, b *Block) error { ...@@ -248,7 +250,7 @@ func Encode(out io.Writer, b *Block) error {
return err return err
} }
} }
if _, err := out.Write([]byte{'\n'}); err != nil { if _, err := out.Write(nl); err != nil {
return err return err
} }
} }
......
...@@ -6,6 +6,7 @@ package pem ...@@ -6,6 +6,7 @@ package pem
import ( import (
"bytes" "bytes"
"io/ioutil"
"reflect" "reflect"
"testing" "testing"
) )
...@@ -116,6 +117,24 @@ func TestLineBreaker(t *testing.T) { ...@@ -116,6 +117,24 @@ func TestLineBreaker(t *testing.T) {
} }
} }
func BenchmarkEncode(b *testing.B) {
data := &Block{Bytes: make([]byte, 65536)}
b.SetBytes(int64(len(data.Bytes)))
for i := 0; i < b.N; i++ {
Encode(ioutil.Discard, data)
}
}
func BenchmarkDecode(b *testing.B) {
block := &Block{Bytes: make([]byte, 65536)}
data := EncodeToMemory(block)
b.SetBytes(int64(len(data)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
Decode(data)
}
}
var pemData = `verify return:0 var pemData = `verify return:0
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
sdlfkjskldfj sdlfkjskldfj
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment