Full Code of valyala/fastrand for AI

master 679a6fad9d7a cached
7 files
9.8 KB
3.5k tokens
20 symbols
1 requests
Download .txt
Repository: valyala/fastrand
Branch: master
Commit: 679a6fad9d7a
Files: 7
Total size: 9.8 KB

Directory structure:
gitextract_9pfnkqbg/

├── .travis.yml
├── LICENSE
├── README.md
├── fastrand.go
├── fastrand_test.go
├── fastrand_timing_test.go
└── go.mod

================================================
FILE CONTENTS
================================================

================================================
FILE: .travis.yml
================================================
language: go

go:
  - 1.7
  - 1.8

script:
  # build test for supported platforms
  - GOOS=linux go build
  - GOOS=darwin go build
  - GOOS=freebsd go build
  - GOARCH=386 go build

  # run tests on a standard platform
  - go test -v ./...



================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2017 Aliaksandr Valialkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
[![Build Status](https://travis-ci.org/valyala/fastrand.svg)](https://travis-ci.org/valyala/fastrand)
[![GoDoc](https://godoc.org/github.com/valyala/fastrand?status.svg)](http://godoc.org/github.com/valyala/fastrand)
[![Go Report](https://goreportcard.com/badge/github.com/valyala/fastrand)](https://goreportcard.com/report/github.com/valyala/fastrand)


# fastrand

Fast pseudorandom number generator.


# Features

- Optimized for speed.
- Performance scales on multiple CPUs.

# How does it work?

It abuses [sync.Pool](https://golang.org/pkg/sync/#Pool) for maintaining
"per-CPU" pseudorandom number generators.

TODO: firgure out how to use real per-CPU pseudorandom number generators.


# Benchmark results


```
$ GOMAXPROCS=1 go test -bench=. github.com/valyala/fastrand
goos: linux
goarch: amd64
pkg: github.com/valyala/fastrand
BenchmarkUint32n                   	50000000	        29.7 ns/op
BenchmarkRNGUint32n                	200000000	         6.50 ns/op
BenchmarkRNGUint32nWithLock        	100000000	        21.5 ns/op
BenchmarkMathRandInt31n            	50000000	        31.8 ns/op
BenchmarkMathRandRNGInt31n         	100000000	        17.9 ns/op
BenchmarkMathRandRNGInt31nWithLock 	50000000	        30.2 ns/op
PASS
ok  	github.com/valyala/fastrand	10.634s
```

```
$ GOMAXPROCS=2 go test -bench=. github.com/valyala/fastrand
goos: linux
goarch: amd64
pkg: github.com/valyala/fastrand
BenchmarkUint32n-2                     	100000000	        17.6 ns/op
BenchmarkRNGUint32n-2                  	500000000	         3.36 ns/op
BenchmarkRNGUint32nWithLock-2          	50000000	        32.0 ns/op
BenchmarkMathRandInt31n-2              	20000000	        51.2 ns/op
BenchmarkMathRandRNGInt31n-2           	100000000	        11.0 ns/op
BenchmarkMathRandRNGInt31nWithLock-2   	20000000	        91.0 ns/op
PASS
ok  	github.com/valyala/fastrand	9.543s
```

```
$ GOMAXPROCS=4 go test -bench=. github.com/valyala/fastrand
goos: linux
goarch: amd64
pkg: github.com/valyala/fastrand
BenchmarkUint32n-4                     	100000000	        14.2 ns/op
BenchmarkRNGUint32n-4                  	500000000	         3.30 ns/op
BenchmarkRNGUint32nWithLock-4          	20000000	        88.7 ns/op
BenchmarkMathRandInt31n-4              	10000000	       145 ns/op
BenchmarkMathRandRNGInt31n-4           	200000000	         8.35 ns/op
BenchmarkMathRandRNGInt31nWithLock-4   	20000000	       102 ns/op
PASS
ok  	github.com/valyala/fastrand	11.534s
```

As you can see, [fastrand.Uint32n](https://godoc.org/github.com/valyala/fastrand#Uint32n)
scales on multiple CPUs, while [rand.Int31n](https://golang.org/pkg/math/rand/#Int31n)
doesn't scale. Their performance is comparable on `GOMAXPROCS=1`,
but `fastrand.Uint32n` runs 3x faster than `rand.Int31n` on `GOMAXPROCS=2`
and 10x faster than `rand.Int31n` on `GOMAXPROCS=4`.


================================================
FILE: fastrand.go
================================================
// Package fastrand implements fast pesudorandom number generator
// that should scale well on multi-CPU systems.
//
// Use crypto/rand instead of this package for generating
// cryptographically secure random numbers.
package fastrand

import (
	"sync"
	"time"
)

// Uint32 returns pseudorandom uint32.
//
// It is safe calling this function from concurrent goroutines.
func Uint32() uint32 {
	v := rngPool.Get()
	if v == nil {
		v = &RNG{}
	}
	r := v.(*RNG)
	x := r.Uint32()
	rngPool.Put(r)
	return x
}

var rngPool sync.Pool

// Uint32n returns pseudorandom uint32 in the range [0..maxN).
//
// It is safe calling this function from concurrent goroutines.
func Uint32n(maxN uint32) uint32 {
	x := Uint32()
	// See http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
	return uint32((uint64(x) * uint64(maxN)) >> 32)
}

// RNG is a pseudorandom number generator.
//
// It is unsafe to call RNG methods from concurrent goroutines.
type RNG struct {
	x uint32
}

// Uint32 returns pseudorandom uint32.
//
// It is unsafe to call this method from concurrent goroutines.
func (r *RNG) Uint32() uint32 {
	for r.x == 0 {
		r.x = getRandomUint32()
	}

	// See https://en.wikipedia.org/wiki/Xorshift
	x := r.x
	x ^= x << 13
	x ^= x >> 17
	x ^= x << 5
	r.x = x
	return x
}

// Uint32n returns pseudorandom uint32 in the range [0..maxN).
//
// It is unsafe to call this method from concurrent goroutines.
func (r *RNG) Uint32n(maxN uint32) uint32 {
	x := r.Uint32()
	// See http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
	return uint32((uint64(x) * uint64(maxN)) >> 32)
}

// Seed sets the r state to n.
func (r *RNG) Seed(n uint32) {
	r.x = n
}

func getRandomUint32() uint32 {
	x := time.Now().UnixNano()
	return uint32((x >> 32) ^ x)
}


================================================
FILE: fastrand_test.go
================================================
package fastrand

import (
	"testing"
)

func TestRNGSeed(t *testing.T) {
	var r RNG
	for _, seed := range []uint32{1, 2, 1234, 432432, 34324432} {
		r.Seed(seed)
		m := make(map[uint32]struct{})
		for i := 0; i < 1e6; i++ {
			n := r.Uint32()
			if _, ok := m[n]; ok {
				t.Fatalf("number %v already exists", n)
			}
			m[n] = struct{}{}
		}
	}
}

func TestUint32(t *testing.T) {
	m := make(map[uint32]struct{})
	for i := 0; i < 1e6; i++ {
		n := Uint32()
		if _, ok := m[n]; ok {
			t.Fatalf("number %v already exists", n)
		}
		m[n] = struct{}{}
	}
}

func TestRNGUint32(t *testing.T) {
	var r RNG
	m := make(map[uint32]struct{})
	for i := 0; i < 1e6; i++ {
		n := r.Uint32()
		if _, ok := m[n]; ok {
			t.Fatalf("number %v already exists", n)
		}
		m[n] = struct{}{}
	}
}

func TestUint32n(t *testing.T) {
	m := make(map[uint32]int)
	for i := 0; i < 1e6; i++ {
		n := Uint32n(1e2)
		if n >= 1e2 {
			t.Fatalf("n > 1000: %v", n)
		}
		m[n]++
	}

	// check distribution
	avg := 1e6 / 1e2
	for k, v := range m {
		p := (float64(v) - float64(avg)) / float64(avg)
		if p < 0 {
			p = -p
		}
		if p > 0.05 {
			t.Fatalf("skew more than 5%% for k=%v: %v", k, p*100)
		}
	}
}

func TestRNGUint32n(t *testing.T) {
	var r RNG
	m := make(map[uint32]int)
	for i := 0; i < 1e6; i++ {
		n := r.Uint32n(1e2)
		if n >= 1e2 {
			t.Fatalf("n > 1000: %v", n)
		}
		m[n]++
	}

	// check distribution
	avg := 1e6 / 1e2
	for k, v := range m {
		p := (float64(v) - float64(avg)) / float64(avg)
		if p < 0 {
			p = -p
		}
		if p > 0.05 {
			t.Fatalf("skew more than 5%% for k=%v: %v", k, p*100)
		}
	}
}


================================================
FILE: fastrand_timing_test.go
================================================
package fastrand

import (
	"math/rand"
	"sync"
	"sync/atomic"
	"testing"
	"unsafe"
)

// BenchSink prevents the compiler from optimizing away benchmark loops.
var BenchSink uint32

func BenchmarkUint32n(b *testing.B) {
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			s += Uint32n(1e6)
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkRNGUint32n(b *testing.B) {
	b.RunParallel(func(pb *testing.PB) {
		var r RNG
		s := uint32(0)
		for pb.Next() {
			s += r.Uint32n(1e6)
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkRNGUint32nWithLock(b *testing.B) {
	var r RNG
	var rMu sync.Mutex
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			rMu.Lock()
			s += r.Uint32n(1e6)
			rMu.Unlock()
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkRNGUint32nArray(b *testing.B) {
	var rr [64]struct {
		r  RNG
		mu sync.Mutex

		// pad prevents from false sharing
		pad [64 - (unsafe.Sizeof(RNG{})+unsafe.Sizeof(sync.Mutex{}))%64]byte
	}
	var n uint32
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			idx := atomic.AddUint32(&n, 1)
			r := &rr[idx%uint32(len(rr))]
			r.mu.Lock()
			s += r.r.Uint32n(1e6)
			r.mu.Unlock()
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkMathRandInt31n(b *testing.B) {
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			s += uint32(rand.Int31n(1e6))
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkMathRandRNGInt31n(b *testing.B) {
	b.RunParallel(func(pb *testing.PB) {
		r := rand.New(rand.NewSource(42))
		s := uint32(0)
		for pb.Next() {
			s += uint32(r.Int31n(1e6))
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkMathRandRNGInt31nWithLock(b *testing.B) {
	r := rand.New(rand.NewSource(42))
	var rMu sync.Mutex
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			rMu.Lock()
			s += uint32(r.Int31n(1e6))
			rMu.Unlock()
		}
		atomic.AddUint32(&BenchSink, s)
	})
}

func BenchmarkMathRandRNGInt31nArray(b *testing.B) {
	var rr [64]struct {
		r  *rand.Rand
		mu sync.Mutex

		// pad prevents from false sharing
		pad [64 - (unsafe.Sizeof(RNG{})+unsafe.Sizeof(sync.Mutex{}))%64]byte
	}
	for i := range rr {
		rr[i].r = rand.New(rand.NewSource(int64(i)))
	}

	var n uint32
	b.RunParallel(func(pb *testing.PB) {
		s := uint32(0)
		for pb.Next() {
			idx := atomic.AddUint32(&n, 1)
			r := &rr[idx%uint32(len(rr))]
			r.mu.Lock()
			s += uint32(r.r.Int31n(1e6))
			r.mu.Unlock()
		}
		atomic.AddUint32(&BenchSink, s)
	})
}


================================================
FILE: go.mod
================================================
module github.com/valyala/fastrand
Download .txt
gitextract_9pfnkqbg/

├── .travis.yml
├── LICENSE
├── README.md
├── fastrand.go
├── fastrand_test.go
├── fastrand_timing_test.go
└── go.mod
Download .txt
SYMBOL INDEX (20 symbols across 3 files)

FILE: fastrand.go
  function Uint32 (line 16) | func Uint32() uint32 {
  function Uint32n (line 32) | func Uint32n(maxN uint32) uint32 {
  type RNG (line 41) | type RNG struct
    method Uint32 (line 48) | func (r *RNG) Uint32() uint32 {
    method Uint32n (line 65) | func (r *RNG) Uint32n(maxN uint32) uint32 {
    method Seed (line 72) | func (r *RNG) Seed(n uint32) {
  function getRandomUint32 (line 76) | func getRandomUint32() uint32 {

FILE: fastrand_test.go
  function TestRNGSeed (line 7) | func TestRNGSeed(t *testing.T) {
  function TestUint32 (line 22) | func TestUint32(t *testing.T) {
  function TestRNGUint32 (line 33) | func TestRNGUint32(t *testing.T) {
  function TestUint32n (line 45) | func TestUint32n(t *testing.T) {
  function TestRNGUint32n (line 68) | func TestRNGUint32n(t *testing.T) {

FILE: fastrand_timing_test.go
  function BenchmarkUint32n (line 14) | func BenchmarkUint32n(b *testing.B) {
  function BenchmarkRNGUint32n (line 24) | func BenchmarkRNGUint32n(b *testing.B) {
  function BenchmarkRNGUint32nWithLock (line 35) | func BenchmarkRNGUint32nWithLock(b *testing.B) {
  function BenchmarkRNGUint32nArray (line 49) | func BenchmarkRNGUint32nArray(b *testing.B) {
  function BenchmarkMathRandInt31n (line 71) | func BenchmarkMathRandInt31n(b *testing.B) {
  function BenchmarkMathRandRNGInt31n (line 81) | func BenchmarkMathRandRNGInt31n(b *testing.B) {
  function BenchmarkMathRandRNGInt31nWithLock (line 92) | func BenchmarkMathRandRNGInt31nWithLock(b *testing.B) {
  function BenchmarkMathRandRNGInt31nArray (line 106) | func BenchmarkMathRandRNGInt31nArray(b *testing.B) {
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (11K chars).
[
  {
    "path": ".travis.yml",
    "chars": 241,
    "preview": "language: go\n\ngo:\n  - 1.7\n  - 1.8\n\nscript:\n  # build test for supported platforms\n  - GOOS=linux go build\n  - GOOS=darwi"
  },
  {
    "path": "LICENSE",
    "chars": 1087,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017 Aliaksandr Valialkin\n\nPermission is hereby granted, free of charge, to any per"
  },
  {
    "path": "README.md",
    "chars": 2816,
    "preview": "[![Build Status](https://travis-ci.org/valyala/fastrand.svg)](https://travis-ci.org/valyala/fastrand)\n[![GoDoc](https://"
  },
  {
    "path": "fastrand.go",
    "chars": 1785,
    "preview": "// Package fastrand implements fast pesudorandom number generator\n// that should scale well on multi-CPU systems.\n//\n// "
  },
  {
    "path": "fastrand_test.go",
    "chars": 1585,
    "preview": "package fastrand\n\nimport (\n\t\"testing\"\n)\n\nfunc TestRNGSeed(t *testing.T) {\n\tvar r RNG\n\tfor _, seed := range []uint32{1, 2"
  },
  {
    "path": "fastrand_timing_test.go",
    "chars": 2533,
    "preview": "package fastrand\n\nimport (\n\t\"math/rand\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"unsafe\"\n)\n\n// BenchSink prevents the compile"
  },
  {
    "path": "go.mod",
    "chars": 35,
    "preview": "module github.com/valyala/fastrand\n"
  }
]

About this extraction

This page contains the full source code of the valyala/fastrand GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (9.8 KB), approximately 3.5k tokens, and a symbol index with 20 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!