Skip to content

Commit

Permalink
better tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zephyrtronium committed Jun 6, 2019
1 parent e030371 commit f124b94
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 8 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2014, 2018 Branden J Brown
Copyright (c) 2014, 2018, 2019 Branden J Brown

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ recommended if avoidable.
An example of running benchmarks might look like:

```
> go test -bench /[KG] -benchtime 10s -timeout 1h
> go test -short -bench /[KG] -benchtime 10s -timeout 1h
goos: windows
goarch: amd64
pkg: github.com/zephyrtronium/crazy
Expand All @@ -83,3 +83,8 @@ In these results, the ns/op measures the time spent to fill an entire 1K or 1G
block, not just to generate a single value). The MB/s throughput is generally a
better indicator of performance. When benchmarking for yourself, use the
`-benchtime` argument to `go test` in order to measure generation of more values.

Note that `-short` is passed to `go test` as well. Some tests concerned with
allowed ranges of Distributions and RNGs generate several hundred million MT64
values. The `-short` flag tells them to generate closer to one million values
instead.
16 changes: 15 additions & 1 deletion distr.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Distribution interface {
}

// Uniform1_2 produces numbers in the interval [1, 2). This interval is chosen
// for speed.
// for speed. Each variate has 52 bits of precision.
type Uniform1_2 struct {
Source
}
Expand All @@ -23,6 +23,20 @@ func (u Uniform1_2) Next() float64 {
return math.Float64frombits(binary.LittleEndian.Uint64(b[:]) | 0x3ff0000000000000)
}

// Uniform0_1 produces numbers in the interval [0, 1). This interval is chosen
// for convenience while still being fast. Each variate has 53 bits of
// precision.
type Uniform0_1 struct {
Source
}

// Next produces a uniform variate in the interval [0, 1).
func (u Uniform0_1) Next() float64 {
b := [8]byte{}
u.Read(b[:])
return float64(binary.LittleEndian.Uint64(b[:])&0x1fffffffffffff) * 1.11022302462515654042e-16
}

// Uniform produces numbers in the interval [Low, High).
type Uniform struct {
Source
Expand Down
43 changes: 42 additions & 1 deletion distr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,50 @@ import "testing"

func TestUniform1_2(t *testing.T) {
d := Uniform1_2{CryptoSeeded(NewMT64(), mt64N)}
for i := 0; i < 1000000; i++ {
n := 1 << 28
if testing.Short() {
n = 1 << 20
}
for i := 0; i < n; i++ {
if x := d.Next(); x < 1 || x >= 2 {
t.Fail()
}
}
}

func TestUniform0_1(t *testing.T) {
d := Uniform0_1{CryptoSeeded(NewMT64(), mt64N)}
n := 1 << 28
if testing.Short() {
n = 1 << 20
}
for i := 0; i < n; i++ {
if x := d.Next(); x < 0 || x >= 1 {

}
}
}

func BenchmarkUniform1_2(b *testing.B) {
d := Uniform1_2{CryptoSeeded(NewMT64(), mt64N)}
b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = d.Next()
}
}

func BenchmarkUniform0_1(b *testing.B) {
d := Uniform0_1{CryptoSeeded(NewMT64(), mt64N)}
b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = d.Next()
}
}

func BenchmarkUniform(b *testing.B) {
d := Uniform{CryptoSeeded(NewMT64(), mt64N), -1, 1}
b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = d.Next()
}
}
24 changes: 24 additions & 0 deletions expo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package crazy

import "testing"

func TestExponential(t *testing.T) {
d := NewExponential(CryptoSeeded(NewMT64(), mt64N), 1)
n := 1 << 28
if testing.Short() {
n = 1 << 20
}
for i := 0; i < n; i++ {
if x := d.Next(); x < 0 {
t.Fail()
}
}
}

func BenchmarkExponential(b *testing.B) {
d := NewExponential(CryptoSeeded(NewMT64(), mt64N), 1)
b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = d.Next()
}
}
3 changes: 1 addition & 2 deletions mt64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import (
"testing"
)

// MT64.SeedIV() uses .Seed(), so testing IV tests both.

func TestMT64Seed(t *testing.T) {
mt := NewMT64()
// MT64.SeedIV() uses .Seed(), so testing IV tests both.
mt.SeedIV(nil)
mt.SeedIV([]byte{mt64N: 0})
mt.SeedIV([]byte{8 * mt64N: 0})
Expand Down
11 changes: 11 additions & 0 deletions normal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package crazy

import "testing"

func BenchmarkNormal(b *testing.B) {
d := NewNormal(CryptoSeeded(NewMT64(), mt64N), 0, 1)
b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = d.Next()
}
}
12 changes: 10 additions & 2 deletions rng_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import (

func TestUintn(t *testing.T) {
r := RNG{CryptoSeeded(NewMT64(), mt64N)}
for i := uint(1); i <= 1000000; i++ {
n := uint(1 << 28)
if testing.Short() {
n = 1 << 20
}
for i := uint(1); i <= n; i++ {
if r.Uintn(i) >= i {
t.Fail()
}
Expand All @@ -16,7 +20,11 @@ func TestUintn(t *testing.T) {

func TestBign(t *testing.T) {
r := RNG{CryptoSeeded(NewMT64(), mt64N)}
for i := 1; i <= 30000; i++ {
n := 1 << 18
if testing.Short() {
n = 1 << 12
}
for i := 1; i <= n; i++ {
v := new(big.Int)
v.Sub(v.SetBit(v, i, 1), big.NewInt(int64(i)))
if r.Bign(v).Cmp(v) >= 0 {
Expand Down

0 comments on commit f124b94

Please sign in to comment.