Source file
src/encoding/gob/timing_test.go
1
2
3
4
5 package gob
6
7 import (
8 "bytes"
9 "io"
10 "os"
11 "reflect"
12 "runtime"
13 "testing"
14 )
15
16 type Bench struct {
17 A int
18 B float64
19 C string
20 D []byte
21 }
22
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) {
25 r, w, err := pipe()
26 if err != nil {
27 b.Fatal("can't get pipe:", err)
28 }
29 v := ctor()
30 enc := NewEncoder(w)
31 dec := NewDecoder(r)
32 for pb.Next() {
33 if err := enc.Encode(v); err != nil {
34 b.Fatal("encode error:", err)
35 }
36 if err := dec.Decode(v); err != nil {
37 b.Fatal("decode error:", err)
38 }
39 }
40 })
41 }
42
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) {
47 r, w, err = os.Pipe()
48 return
49 })
50 }
51
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) {
56 var buf bytes.Buffer
57 return &buf, &buf, nil
58 })
59 }
60
61 func BenchmarkEndToEndSliceByteBuffer(b *testing.B) {
62 benchmarkEndToEnd(b, func() interface{} {
63 v := &Bench{7, 3.2, "now is the time", nil}
64 Register(v)
65 arr := make([]interface{}, 100)
66 for i := range arr {
67 arr[i] = v
68 }
69 return &arr
70 }, func() (r io.Reader, w io.Writer, err error) {
71 var buf bytes.Buffer
72 return &buf, &buf, nil
73 })
74 }
75
76 func TestCountEncodeMallocs(t *testing.T) {
77 if testing.Short() {
78 t.Skip("skipping malloc count in short mode")
79 }
80 if runtime.GOMAXPROCS(0) > 1 {
81 t.Skip("skipping; GOMAXPROCS>1")
82 }
83
84 const N = 1000
85
86 var buf bytes.Buffer
87 enc := NewEncoder(&buf)
88 bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
89
90 allocs := testing.AllocsPerRun(N, func() {
91 err := enc.Encode(bench)
92 if err != nil {
93 t.Fatal("encode:", err)
94 }
95 })
96 if allocs != 0 {
97 t.Fatalf("mallocs per encode of type Bench: %v; wanted 0\n", allocs)
98 }
99 }
100
101 func TestCountDecodeMallocs(t *testing.T) {
102 if testing.Short() {
103 t.Skip("skipping malloc count in short mode")
104 }
105 if runtime.GOMAXPROCS(0) > 1 {
106 t.Skip("skipping; GOMAXPROCS>1")
107 }
108
109 const N = 1000
110
111 var buf bytes.Buffer
112 enc := NewEncoder(&buf)
113 bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
114
115
116 testing.AllocsPerRun(N, func() {
117 err := enc.Encode(bench)
118 if err != nil {
119 t.Fatal("encode:", err)
120 }
121 })
122
123 dec := NewDecoder(&buf)
124 allocs := testing.AllocsPerRun(N, func() {
125 *bench = Bench{}
126 err := dec.Decode(&bench)
127 if err != nil {
128 t.Fatal("decode:", err)
129 }
130 })
131 if allocs != 3 {
132 t.Fatalf("mallocs per decode of type Bench: %v; wanted 3\n", allocs)
133 }
134 }
135
136 func benchmarkEncodeSlice(b *testing.B, a interface{}) {
137 b.ResetTimer()
138 b.RunParallel(func(pb *testing.PB) {
139 var buf bytes.Buffer
140 enc := NewEncoder(&buf)
141
142 for pb.Next() {
143 buf.Reset()
144 err := enc.Encode(a)
145 if err != nil {
146 b.Fatal(err)
147 }
148 }
149 })
150 }
151
152 func BenchmarkEncodeComplex128Slice(b *testing.B) {
153 a := make([]complex128, 1000)
154 for i := range a {
155 a[i] = 1.2 + 3.4i
156 }
157 benchmarkEncodeSlice(b, a)
158 }
159
160 func BenchmarkEncodeFloat64Slice(b *testing.B) {
161 a := make([]float64, 1000)
162 for i := range a {
163 a[i] = 1.23e4
164 }
165 benchmarkEncodeSlice(b, a)
166 }
167
168 func BenchmarkEncodeInt32Slice(b *testing.B) {
169 a := make([]int32, 1000)
170 for i := range a {
171 a[i] = int32(i * 100)
172 }
173 benchmarkEncodeSlice(b, a)
174 }
175
176 func BenchmarkEncodeStringSlice(b *testing.B) {
177 a := make([]string, 1000)
178 for i := range a {
179 a[i] = "now is the time"
180 }
181 benchmarkEncodeSlice(b, a)
182 }
183
184 func BenchmarkEncodeInterfaceSlice(b *testing.B) {
185 a := make([]interface{}, 1000)
186 for i := range a {
187 a[i] = "now is the time"
188 }
189 benchmarkEncodeSlice(b, a)
190 }
191
192
193 type benchmarkBuf struct {
194 offset int
195 data []byte
196 }
197
198 func (b *benchmarkBuf) Read(p []byte) (n int, err error) {
199 n = copy(p, b.data[b.offset:])
200 if n == 0 {
201 return 0, io.EOF
202 }
203 b.offset += n
204 return
205 }
206
207 func (b *benchmarkBuf) ReadByte() (c byte, err error) {
208 if b.offset >= len(b.data) {
209 return 0, io.EOF
210 }
211 c = b.data[b.offset]
212 b.offset++
213 return
214 }
215
216 func (b *benchmarkBuf) reset() {
217 b.offset = 0
218 }
219
220 func benchmarkDecodeSlice(b *testing.B, a interface{}) {
221 var buf bytes.Buffer
222 enc := NewEncoder(&buf)
223 err := enc.Encode(a)
224 if err != nil {
225 b.Fatal(err)
226 }
227
228 ra := reflect.ValueOf(a)
229 rt := ra.Type()
230 b.ResetTimer()
231
232 b.RunParallel(func(pb *testing.PB) {
233
234 rp := reflect.New(rt)
235 rp.Elem().Set(reflect.MakeSlice(rt, ra.Len(), ra.Cap()))
236 p := rp.Interface()
237
238 bbuf := benchmarkBuf{data: buf.Bytes()}
239
240 for pb.Next() {
241 bbuf.reset()
242 dec := NewDecoder(&bbuf)
243 err := dec.Decode(p)
244 if err != nil {
245 b.Fatal(err)
246 }
247 }
248 })
249 }
250
251 func BenchmarkDecodeComplex128Slice(b *testing.B) {
252 a := make([]complex128, 1000)
253 for i := range a {
254 a[i] = 1.2 + 3.4i
255 }
256 benchmarkDecodeSlice(b, a)
257 }
258
259 func BenchmarkDecodeFloat64Slice(b *testing.B) {
260 a := make([]float64, 1000)
261 for i := range a {
262 a[i] = 1.23e4
263 }
264 benchmarkDecodeSlice(b, a)
265 }
266
267 func BenchmarkDecodeInt32Slice(b *testing.B) {
268 a := make([]int32, 1000)
269 for i := range a {
270 a[i] = 1234
271 }
272 benchmarkDecodeSlice(b, a)
273 }
274
275 func BenchmarkDecodeStringSlice(b *testing.B) {
276 a := make([]string, 1000)
277 for i := range a {
278 a[i] = "now is the time"
279 }
280 benchmarkDecodeSlice(b, a)
281 }
282
283 func BenchmarkDecodeInterfaceSlice(b *testing.B) {
284 a := make([]interface{}, 1000)
285 for i := range a {
286 a[i] = "now is the time"
287 }
288 benchmarkDecodeSlice(b, a)
289 }
290
291 func BenchmarkDecodeMap(b *testing.B) {
292 count := 1000
293 m := make(map[int]int, count)
294 for i := 0; i < count; i++ {
295 m[i] = i
296 }
297 var buf bytes.Buffer
298 enc := NewEncoder(&buf)
299 err := enc.Encode(m)
300 if err != nil {
301 b.Fatal(err)
302 }
303 bbuf := benchmarkBuf{data: buf.Bytes()}
304 b.ResetTimer()
305 for i := 0; i < b.N; i++ {
306 var rm map[int]int
307 bbuf.reset()
308 dec := NewDecoder(&bbuf)
309 err := dec.Decode(&rm)
310 if err != nil {
311 b.Fatal(i, err)
312 }
313 }
314 }
315
View as plain text