1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
23 func benchmarkEndToEnd(b
*testing
.B
, ctor
func() interface{}, pipe
func() (r io
.Reader
, w io
.Writer
, err error
)) {
24 b
.RunParallel(func(pb
*testing
.PB
) {
27 b
.Fatal("can't get pipe:", err
)
33 if err
:= enc
.Encode(v
); err
!= nil {
34 b
.Fatal("encode error:", err
)
36 if err
:= dec
.Decode(v
); err
!= nil {
37 b
.Fatal("decode error:", err
)
43 func BenchmarkEndToEndPipe(b
*testing
.B
) {
44 benchmarkEndToEnd(b
, func() interface{} {
45 return &Bench
{7, 3.2, "now is the time", bytes
.Repeat([]byte("for all good men"), 100)}
46 }, func() (r io
.Reader
, w io
.Writer
, err error
) {
52 func BenchmarkEndToEndByteBuffer(b
*testing
.B
) {
53 benchmarkEndToEnd(b
, func() interface{} {
54 return &Bench
{7, 3.2, "now is the time", bytes
.Repeat([]byte("for all good men"), 100)}
55 }, func() (r io
.Reader
, w io
.Writer
, err error
) {
57 return &buf
, &buf
, nil
61 func BenchmarkEndToEndSliceByteBuffer(b
*testing
.B
) {
62 benchmarkEndToEnd(b
, func() interface{} {
63 v
:= &Bench
{7, 3.2, "now is the time", nil}
65 arr
:= make([]interface{}, 100)
70 }, func() (r io
.Reader
, w io
.Writer
, err error
) {
72 return &buf
, &buf
, nil
76 func TestCountEncodeMallocs(t
*testing
.T
) {
78 t
.Skip("skipping malloc count in short mode")
80 if runtime
.GOMAXPROCS(0) > 1 {
81 t
.Skip("skipping; GOMAXPROCS>1")
87 enc
:= NewEncoder(&buf
)
88 bench
:= &Bench
{7, 3.2, "now is the time", []byte("for all good men")}
90 allocs
:= testing
.AllocsPerRun(N
, func() {
91 err
:= enc
.Encode(bench
)
93 t
.Fatal("encode:", err
)
97 t
.Fatalf("mallocs per encode of type Bench: %v; wanted 0\n", allocs
)
101 func TestCountDecodeMallocs(t
*testing
.T
) {
103 t
.Skip("skipping malloc count in short mode")
105 if runtime
.GOMAXPROCS(0) > 1 {
106 t
.Skip("skipping; GOMAXPROCS>1")
112 enc
:= NewEncoder(&buf
)
113 bench
:= &Bench
{7, 3.2, "now is the time", []byte("for all good men")}
115 // Fill the buffer with enough to decode
116 testing
.AllocsPerRun(N
, func() {
117 err
:= enc
.Encode(bench
)
119 t
.Fatal("encode:", err
)
123 dec
:= NewDecoder(&buf
)
124 allocs
:= testing
.AllocsPerRun(N
, func() {
126 err
:= dec
.Decode(&bench
)
128 t
.Fatal("decode:", err
)
132 t
.Fatalf("mallocs per decode of type Bench: %v; wanted 3\n", allocs
)
136 func benchmarkEncodeSlice(b
*testing
.B
, a
interface{}) {
138 b
.RunParallel(func(pb
*testing
.PB
) {
140 enc
:= NewEncoder(&buf
)
152 func BenchmarkEncodeComplex128Slice(b
*testing
.B
) {
153 a
:= make([]complex128
, 1000)
157 benchmarkEncodeSlice(b
, a
)
160 func BenchmarkEncodeFloat64Slice(b
*testing
.B
) {
161 a
:= make([]float64, 1000)
165 benchmarkEncodeSlice(b
, a
)
168 func BenchmarkEncodeInt32Slice(b
*testing
.B
) {
169 a
:= make([]int32, 1000)
171 a
[i
] = int32(i
* 100)
173 benchmarkEncodeSlice(b
, a
)
176 func BenchmarkEncodeStringSlice(b
*testing
.B
) {
177 a
:= make([]string, 1000)
179 a
[i
] = "now is the time"
181 benchmarkEncodeSlice(b
, a
)
184 func BenchmarkEncodeInterfaceSlice(b
*testing
.B
) {
185 a
:= make([]interface{}, 1000)
187 a
[i
] = "now is the time"
189 benchmarkEncodeSlice(b
, a
)
192 // benchmarkBuf is a read buffer we can reset
193 type benchmarkBuf
struct {
198 func (b
*benchmarkBuf
) Read(p
[]byte) (n
int, err error
) {
199 n
= copy(p
, b
.data
[b
.offset
:])
207 func (b
*benchmarkBuf
) ReadByte() (c
byte, err error
) {
208 if b
.offset
>= len(b
.data
) {
216 func (b
*benchmarkBuf
) reset() {
220 func benchmarkDecodeSlice(b
*testing
.B
, a
interface{}) {
222 enc
:= NewEncoder(&buf
)
228 ra
:= reflect
.ValueOf(a
)
232 b
.RunParallel(func(pb
*testing
.PB
) {
233 // TODO(#19025): Move per-thread allocation before ResetTimer.
234 rp
:= reflect
.New(rt
)
235 rp
.Elem().Set(reflect
.MakeSlice(rt
, ra
.Len(), ra
.Cap()))
238 bbuf
:= benchmarkBuf
{data
: buf
.Bytes()}
242 dec
:= NewDecoder(&bbuf
)
251 func BenchmarkDecodeComplex128Slice(b
*testing
.B
) {
252 a
:= make([]complex128
, 1000)
256 benchmarkDecodeSlice(b
, a
)
259 func BenchmarkDecodeFloat64Slice(b
*testing
.B
) {
260 a
:= make([]float64, 1000)
264 benchmarkDecodeSlice(b
, a
)
267 func BenchmarkDecodeInt32Slice(b
*testing
.B
) {
268 a
:= make([]int32, 1000)
272 benchmarkDecodeSlice(b
, a
)
275 func BenchmarkDecodeStringSlice(b
*testing
.B
) {
276 a
:= make([]string, 1000)
278 a
[i
] = "now is the time"
280 benchmarkDecodeSlice(b
, a
)
283 func BenchmarkDecodeInterfaceSlice(b
*testing
.B
) {
284 a
:= make([]interface{}, 1000)
286 a
[i
] = "now is the time"
288 benchmarkDecodeSlice(b
, a
)
291 func BenchmarkDecodeMap(b
*testing
.B
) {
293 m
:= make(map[int]int, count
)
294 for i
:= 0; i
< count
; i
++ {
298 enc
:= NewEncoder(&buf
)
303 bbuf
:= benchmarkBuf
{data
: buf
.Bytes()}
305 for i
:= 0; i
< b
.N
; i
++ {
308 dec
:= NewDecoder(&bbuf
)
309 err
:= dec
.Decode(&rm
)