rand

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2022 License: MPL-2.0 Imports: 5 Imported by: 30

README

rand PkgGoDev CI

Fast, high quality alternative to math/rand and golang.org/x/exp/rand.

Compared to these packages, pgregory.net/rand:

  • is API-compatible with all *rand.Rand methods,
  • is significantly faster, while providing state-of-the-art generator quality,
  • has simpler generator initialization:
    • rand.New() instead of rand.New(rand.NewSource(time.Now().UnixNano()))
    • rand.New(1) instead of rand.New(rand.NewSource(1))
  • is deliberately not providing top-level functions like Float64() or Int() and the Source interface.

Benchmarks

All benchmarks were run on Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz (frequency-locked), linux/amd64.

Compared to math/rand:

name                    old time/op    new time/op    delta
Rand_New-8                18.5µs ± 0%     0.1µs ± 3%   -99.48%  (p=0.000 n=10+10)
Rand_ExpFloat64-8         12.4ns ± 6%     8.6ns ± 0%   -30.16%  (p=0.000 n=10+10)
Rand_Float32-8            10.7ns ± 5%     3.5ns ± 1%   -67.77%  (p=0.000 n=10+9)
Rand_Float64-8            6.93ns ± 3%    4.09ns ± 1%   -41.00%  (p=0.000 n=9+9)
Rand_Int-8                6.10ns ± 0%    3.82ns ± 0%   -37.38%  (p=0.000 n=8+10)
Rand_Int31-8              6.02ns ± 2%    2.80ns ± 1%   -53.47%  (p=0.000 n=9+10)
Rand_Int31n-8             16.2ns ± 1%     4.1ns ± 2%   -74.94%  (p=0.000 n=8+10)
Rand_Int31n_Big-8         16.1ns ± 1%     4.0ns ± 1%   -74.87%  (p=0.000 n=8+9)
Rand_Int63-8              6.02ns ± 2%    3.82ns ± 0%   -36.50%  (p=0.000 n=10+10)
Rand_Int63n-8             40.8ns ± 1%     5.9ns ± 0%   -85.62%  (p=0.000 n=8+10)
Rand_Int63n_Big-8         39.9ns ± 0%    14.4ns ± 0%   -63.99%  (p=0.000 n=9+9)
Rand_Intn-8               18.4ns ± 1%     5.9ns ± 0%   -68.03%  (p=0.000 n=9+9)
Rand_Intn_Big-8           43.0ns ± 1%    14.3ns ± 0%   -66.88%  (p=0.000 n=8+9)
Rand_NormFloat64-8        13.4ns ± 3%    10.1ns ± 1%   -25.20%  (p=0.000 n=10+10)
Rand_Perm-8               1.30µs ± 7%    0.42µs ± 2%   -67.38%  (p=0.000 n=9+10)
Rand_Read-8                446ns ± 8%     135ns ± 1%   -69.87%  (p=0.000 n=9+10)
Rand_Seed-8               17.7µs ± 3%     0.0µs ± 0%   -99.74%  (p=0.000 n=10+9)
Rand_Shuffle-8             673ns ± 5%     412ns ± 2%   -38.75%  (p=0.000 n=9+9)
Rand_ShuffleOverhead-8     554ns ± 3%     308ns ± 1%   -44.44%  (p=0.000 n=10+10)
Rand_Uint32-8             5.88ns ± 4%    2.82ns ± 1%   -52.02%  (p=0.000 n=9+9)
Rand_Uint64-8             8.68ns ± 2%    4.30ns ±10%   -50.44%  (p=0.000 n=10+10)

name                    old alloc/op   new alloc/op   delta
Rand_New-8                5.42kB ± 0%    0.05kB ± 0%   -99.12%  (p=0.000 n=10+10)
Rand_Perm-8                 416B ± 0%      416B ± 0%      ~     (all equal)

name                    old allocs/op  new allocs/op  delta
Rand_New-8                  2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=10+10)
Rand_Perm-8                 1.00 ± 0%      1.00 ± 0%      ~     (all equal)

name                    old speed      new speed      delta
Rand_Read-8              568MB/s ±10%  1903MB/s ± 1%  +235.11%  (p=0.000 n=10+10)
Rand_Uint32-8            680MB/s ± 4%  1418MB/s ± 1%  +108.36%  (p=0.000 n=9+9)
Rand_Uint64-8            922MB/s ± 2%  1869MB/s ±10%  +102.73%  (p=0.000 n=10+10)

Compared to golang.org/x/exp/rand:

name                    old time/op    new time/op    delta
Rand_New-8                 104ns ± 5%      97ns ± 3%    -6.83%  (p=0.000 n=10+10)
Rand_ExpFloat64-8         13.3ns ± 8%     8.6ns ± 0%   -34.92%  (p=0.000 n=10+10)
Rand_Float32-8            15.1ns ±10%     3.5ns ± 1%   -77.11%  (p=0.000 n=9+9)
Rand_Float64-8            11.4ns ± 1%     4.1ns ± 1%   -64.02%  (p=0.000 n=10+9)
Rand_Int-8                7.37ns ± 2%    3.82ns ± 0%   -48.14%  (p=0.000 n=9+10)
Rand_Int31-8              7.32ns ± 2%    2.80ns ± 1%   -61.73%  (p=0.000 n=10+10)
Rand_Int31n-8             27.0ns ± 1%     4.1ns ± 2%   -85.01%  (p=0.000 n=10+10)
Rand_Int31n_Big-8         27.1ns ± 1%     4.0ns ± 1%   -85.06%  (p=0.000 n=9+9)
Rand_Int63-8              7.29ns ± 4%    3.82ns ± 0%   -47.56%  (p=0.000 n=10+10)
Rand_Int63n-8             27.7ns ± 6%     5.9ns ± 0%   -78.85%  (p=0.000 n=10+10)
Rand_Int63n_Big-8         43.1ns ± 3%    14.4ns ± 0%   -66.67%  (p=0.000 n=10+9)
Rand_Intn-8               26.8ns ± 6%     5.9ns ± 0%   -78.12%  (p=0.000 n=10+9)
Rand_Intn_Big-8           40.1ns ± 0%    14.3ns ± 0%   -64.45%  (p=0.000 n=8+9)
Rand_NormFloat64-8        14.2ns ± 3%    10.1ns ± 1%   -29.18%  (p=0.000 n=10+10)
Rand_Perm-8               1.61µs ±10%    0.42µs ± 2%   -73.66%  (p=0.000 n=9+10)
Rand_Read-8                473ns ± 2%     135ns ± 1%   -71.56%  (p=0.000 n=10+10)
Rand_Seed-8               5.85ns ± 2%   46.27ns ± 0%  +691.44%  (p=0.000 n=8+9)
Rand_Shuffle-8            1.49µs ± 1%    0.41µs ± 2%   -72.33%  (p=0.000 n=10+9)
Rand_ShuffleOverhead-8    1.33µs ± 2%    0.31µs ± 1%   -76.92%  (p=0.000 n=10+10)
Rand_Uint32-8             6.97ns ± 1%    2.82ns ± 1%   -59.54%  (p=0.000 n=9+9)
Rand_Uint64-8             6.99ns ± 1%    4.30ns ±10%   -38.44%  (p=0.000 n=9+10)
Rand_Uint64n-8            27.5ns ± 8%     6.2ns ±10%   -77.42%  (p=0.000 n=10+10)
Rand_Uint64n_Big-8        41.4ns ± 3%     9.8ns ± 1%   -76.36%  (p=0.000 n=10+9)
Rand_MarshalBinary-8      40.6ns ± 9%     6.3ns ± 4%   -84.59%  (p=0.000 n=10+10)
Rand_UnmarshalBinary-8    5.40ns ± 5%    6.15ns ± 0%   +13.88%  (p=0.000 n=10+10)

name                    old alloc/op   new alloc/op   delta
Rand_New-8                 48.0B ± 0%     48.0B ± 0%      ~     (all equal)
Rand_Perm-8                 416B ± 0%      416B ± 0%      ~     (all equal)
Rand_MarshalBinary-8       16.0B ± 0%      0.0B       -100.00%  (p=0.000 n=10+10)
Rand_UnmarshalBinary-8     0.00B          0.00B           ~     (all equal)

name                    old allocs/op  new allocs/op  delta
Rand_New-8                  2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=10+10)
Rand_Perm-8                 1.00 ± 0%      1.00 ± 0%      ~     (all equal)
Rand_MarshalBinary-8        1.00 ± 0%      0.00       -100.00%  (p=0.000 n=10+10)
Rand_UnmarshalBinary-8      0.00           0.00           ~     (all equal)

name                    old speed      new speed      delta
Rand_Read-8              541MB/s ± 2%  1903MB/s ± 1%  +251.62%  (p=0.000 n=10+10)
Rand_Uint32-8            574MB/s ± 1%  1418MB/s ± 1%  +147.16%  (p=0.000 n=9+9)
Rand_Uint64-8           1.15GB/s ± 1%  1.87GB/s ±10%   +63.23%  (p=0.000 n=9+10)

Status

pgregory.net/rand is alpha software. API breakage and bugs should be expected before 1.0.

License

pgregory.net/rand is licensed under the Mozilla Public License Version 2.0.

Documentation

Overview

Package rand implements pseudo-random number generators unsuitable for security-sensitive work.

This package is considerably faster and generates higher quality random than the math/rand package. However, this package's outputs might be easily predictable regardless of how it's seeded. For random numbers suitable for security-sensitive work, see the crypto/rand package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Rand

type Rand struct {
	// contains filtered or unexported fields
}

Rand is a pseudo-random number generator based on the SFC64 algorithm by Chris Doty-Humphrey.

SFC64 has 256 bits of state, average period of ~2^255 and minimum period of at least 2^64. Generators returned by New (with empty or distinct seeds) are guaranteed to not run into each other for at least 2^64 iterations.

func New

func New(seed ...uint64) *Rand

New returns an initialized generator. If seed is empty, generator is initialized to a non-deterministic state. Otherwise, generator is seeded with the values from seed. New panics if len(seed) > 3.

func (*Rand) ExpFloat64

func (r *Rand) ExpFloat64() float64

ExpFloat64 returns an exponentially distributed float64 in the range (0, +math.MaxFloat64] with an exponential distribution whose rate parameter (lambda) is 1 and whose mean is 1/lambda (1). To produce a distribution with a different rate parameter, callers can adjust the output using:

sample = ExpFloat64() / desiredRateParameter

func (*Rand) Float32

func (r *Rand) Float32() float32

Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0, 1.0).

func (*Rand) Float64

func (r *Rand) Float64() float64

Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0, 1.0).

func (*Rand) Int

func (r *Rand) Int() int

Int returns a non-negative pseudo-random int.

func (*Rand) Int31

func (r *Rand) Int31() int32

Int31 returns a non-negative pseudo-random 31-bit integer as an int32.

func (*Rand) Int31n

func (r *Rand) Int31n(n int32) int32

Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0, n). It panics if n <= 0.

func (*Rand) Int63

func (r *Rand) Int63() int64

Int63 returns a non-negative pseudo-random 63-bit integer as an int64.

func (*Rand) Int63n

func (r *Rand) Int63n(n int64) int64

Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0, n). It panics if n <= 0.

func (*Rand) Intn

func (r *Rand) Intn(n int) int

Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0, n). It panics if n <= 0.

func (*Rand) MarshalBinary

func (r *Rand) MarshalBinary() ([]byte, error)

MarshalBinary returns the binary representation of the current state of the generator.

func (*Rand) NormFloat64

func (r *Rand) NormFloat64() float64

NormFloat64 returns a normally distributed float64 in the range -math.MaxFloat64 through +math.MaxFloat64 inclusive, with standard normal distribution (mean = 0, stddev = 1). To produce a different normal distribution, callers can adjust the output using:

sample = NormFloat64() * desiredStdDev + desiredMean

func (*Rand) Perm

func (r *Rand) Perm(n int) []int

Perm returns, as a slice of n ints, a pseudo-random permutation of the integers in the half-open interval [0, n).

func (*Rand) Read

func (r *Rand) Read(p []byte) (n int, err error)

Read generates len(p) random bytes and writes them into p. It always returns len(p) and a nil error.

func (*Rand) Seed

func (r *Rand) Seed(seed uint64)

Seed uses the provided seed value to initialize the generator to a deterministic state.

func (*Rand) Shuffle

func (r *Rand) Shuffle(n int, swap func(i, j int))

Shuffle pseudo-randomizes the order of elements. n is the number of elements. Shuffle panics if n < 0. swap swaps the elements with indexes i and j.

func (*Rand) Uint32

func (r *Rand) Uint32() uint32

Uint32 returns a pseudo-random 32-bit value as a uint32.

func (*Rand) Uint32n

func (r *Rand) Uint32n(n uint32) uint32

Uint32n returns, as a uint32, a pseudo-random number in [0, n). Uint32n(0) returns 0.

func (*Rand) Uint64

func (r *Rand) Uint64() uint64

Uint64 returns a pseudo-random 64-bit value as a uint64.

func (*Rand) Uint64n

func (r *Rand) Uint64n(n uint64) uint64

Uint64n returns, as a uint64, a pseudo-random number in [0, n). Uint64n(0) returns 0.

func (*Rand) UnmarshalBinary

func (r *Rand) UnmarshalBinary(data []byte) error

UnmarshalBinary sets the state of the generator to the state represented in data.

type Zipf

type Zipf struct {
	// contains filtered or unexported fields
}

A Zipf generates Zipf distributed variates.

func NewZipf

func NewZipf(r *Rand, s float64, v float64, imax uint64) *Zipf

NewZipf returns a Zipf variate generator. The generator generates values k ∈ [0, imax] such that P(k) is proportional to (v + k) ** (-s). Requirements: s > 1 and v >= 1.

func (*Zipf) Uint64

func (z *Zipf) Uint64() uint64

Uint64 returns a value drawn from the Zipf distribution described by the Zipf object.

Directories

Path Synopsis
misc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL