github.com/xaionaro-go/rand@v0.0.0-20191005105903-aba1befc54a5/mathrand/read_test.go (about)

     1  package mathrand_test
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"sync"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	lukechampine "lukechampine.com/frand"
    12  )
    13  
    14  const (
    15  	allowedAvgError = 1 << 10
    16  	initialSeed     = 8963315421273233617
    17  )
    18  
    19  func testRead(t *testing.T, readFunc func([]byte) (int, error)) {
    20  	errCount := 0
    21  	for i := 6; i <= 20; i += 2 {
    22  		count := 1 << i
    23  
    24  		b := make([]byte, count)
    25  
    26  		for j := 0; j < 21-i; j++ {
    27  			_, _ = readFunc(b)
    28  
    29  			m := map[uint8]uint64{}
    30  			var sum uint64
    31  			for _, v := range b {
    32  				sum += uint64(v)
    33  				m[v]++
    34  			}
    35  
    36  			avg := float64(sum) / float64(len(b))
    37  			if !assert.True(t, avg > 128-allowedAvgError/float64(i*i), fmt.Sprintf("%v: %v", i, avg)) {
    38  				errCount++
    39  			}
    40  			if !assert.True(t, avg < 128+allowedAvgError/float64(i*i), fmt.Sprintf("%v: %v", i, avg)) {
    41  				errCount++
    42  			}
    43  
    44  			for v := 0; v < (1 << 8); v++ {
    45  				c := m[uint8(v)]
    46  				if !assert.True(t, float64(c)*1.15+50 > float64(count)/(1<<8), fmt.Sprintf("%v: m[%v]==%v far from %v", i, v, c, count/256)) {
    47  					errCount++
    48  				}
    49  				if !assert.True(t, float64(c)*0.85-30 < float64(count)/(1<<8), fmt.Sprintf("%v: m[%v]==%v far from %v", i, v, c, count/256)) {
    50  					errCount++
    51  				}
    52  			}
    53  		}
    54  	}
    55  	if errCount > 0 {
    56  		t.Fatalf("errCount == %v", errCount)
    57  	}
    58  }
    59  
    60  func TestStandardRead(t *testing.T) {
    61  	testRead(t, rand.Read)
    62  }
    63  
    64  func BenchmarkStandardRead1(b *testing.B) {
    65  	benchmarkRead(b, rand.Read, 1)
    66  }
    67  func BenchmarkStandardRead16(b *testing.B) {
    68  	benchmarkRead(b, rand.Read, 16)
    69  }
    70  func BenchmarkStandardRead1024(b *testing.B) {
    71  	benchmarkRead(b, rand.Read, 1024)
    72  }
    73  func BenchmarkStandardRead65536(b *testing.B) {
    74  	benchmarkRead(b, rand.Read, 65536)
    75  }
    76  func BenchmarkStandardRead16777216(b *testing.B) {
    77  	benchmarkRead(b, rand.Read, 16777216)
    78  }
    79  
    80  func BenchmarkLukechampine1(b *testing.B) {
    81  	benchmarkRead(b, lukechampine.Read, 1)
    82  }
    83  func BenchmarkLukechampine1024(b *testing.B) {
    84  	benchmarkRead(b, lukechampine.Read, 1024)
    85  }
    86  func BenchmarkLukechampine65536(b *testing.B) {
    87  	benchmarkRead(b, lukechampine.Read, 65536)
    88  }
    89  func BenchmarkLukechampine16777216(b *testing.B) {
    90  	benchmarkRead(b, lukechampine.Read, 16777216)
    91  }
    92  
    93  func benchmarkRead(b *testing.B, readFunc func([]byte) (int, error), bufSize uint) {
    94  	buf := make([]byte, bufSize)
    95  	b.SetBytes(int64(bufSize))
    96  	b.ResetTimer()
    97  	for i := 0; i < b.N; i++ {
    98  		_, _ = readFunc(buf)
    99  	}
   100  }
   101  
   102  func benchmarkConcurrentRead(b *testing.B, readFunc func([]byte) (int, error), bufSize uint) {
   103  	bufPool := sync.Pool{New: func() interface{} { return &[][]byte{make([]byte, bufSize)}[0] }}
   104  	b.SetBytes(int64(bufSize))
   105  	b.ResetTimer()
   106  	b.RunParallel(func(pb *testing.PB) {
   107  		buf := bufPool.Get().(*[]byte)
   108  		for pb.Next() {
   109  			_, _ = readFunc(*buf)
   110  		}
   111  		bufPool.Put(buf)
   112  	})
   113  }