github.com/freddyisaac/sicortex-golang@v0.0.0-20231019035217-e03519e66f60/src/encoding/gob/timing_test.go (about)

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