Fast and scalable pseudorandom generator for Go

Overview

Build Status GoDoc Go Report

fastrand

Fast pseudorandom number generator.

Features

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

How does it work?

It abuses 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 scales on multiple CPUs, while 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.

You might also like...
A prototype code-generator library for golang.

A prototype code-generator library for golang.

 Julia Set Generator Written In Golang
Julia Set Generator Written In Golang

Julia Set Generator Written In Golang This is a simple (naive) Julia Set generator written in Golang. The project utilizes concurrent workers to speed

Code generator that generates boilerplate code for a go http server

http-bootstrapper This is a code generator that uses go templates to generate a bootstrap code for a go http server. Usage Generate go http server cod

Transitland routes geometry generator from gtfs shapes

Transitland route geometry generator Generate your transitland route shapes from gtfs trips - WIP This project aims to generate transitland gtfs route

Golemon - A Go port of the lemon parser generator

Go lemon port A port of the Lemon Parser to Go. State This work was done entirel

Golang Fake data generator

Fake data generator. Written in Go Installation Faker requires Go 1.17 go get

Rhythm - Euclidean Rhythm generator written in Go with nested circular lists 🤹

rhythm Euclidean Rhythm generator written in Go with nested circular lists 🤹 Us

MCsniperGO, a fast, efficient, and feature-packed minecraft name sniper.

MCsniperGO This project was made possible by my donators Usage This sniper is in it's beta stage, meaning bugs should be expected. Easy installation d

Fast, lightweight and NOT reliable tool for downloading tons of images.

image-download-tool Fast, lightweight and NOT reliable tool for downloading tons of images. How to use Run .exe with --help flag Create json file with

Comments
  • Add Seed() function to API?

    Add Seed() function to API?

    Library is really great for benchmark purposes when one needs to generate lots of random data to feed to some procesing.

    But lack of Seed() function makes it difficult to debug code.

    opened by seletskiy 2
  • RNG seeding using crypto/rand uint64

    RNG seeding using crypto/rand uint64

    • To rebase once #1, #2 and #3 are merged.
    • It was taking 127ns before it now takes 550ns but this is only done once per RNG
    • I think this is very much reasonable as no user would create a very large number (billions+) of goroutines. And it allows our RNGs to be seeded properly 👍
    opened by qdm12 0
  • Is this per CPU or per goroutine?

    Is this per CPU or per goroutine?

    Hello, first thanks for that small code, it's interesting!

    I'm trying to solve this with it, for the fun of it.

    Now regarding the sync.Pool, I'm not sure this is so much per CPU than it is per goroutine.

    If you have 1000 goroutines at the same time, there will be 1000 RNG objects (well just 1000x 1 uint32 really so that's fine memory wise).

    Indeed if you have 4 CPU intensive goroutines on a 4 core CPU, there will be one RNG per core but that's a particular case.

    Should we mention that in the readme?

    There is also another problem: if you launch 1000 goroutines at start, it 'could' create 1000 RNG initialized with the same time (unlikely, but it can happen on certain systems with bad time resolution) and that can lead to a quite bad pseudo randomness.

    Maybe a solution would be to use crypto/rand the first time when creating the RNG object via the sync.Pool's New field function?

    opened by qdm12 0
Owner
Aliaksandr Valialkin
Working on @VictoriaMetrics
Aliaksandr Valialkin
A simple API for computing diffs of your documents over the time built on a scalable technology stack.

Diffme API WIP - this is an API to compute diffs between documents. It serves as a way to easily create audit logs for documents in your system, think

diffme 11 Sep 8, 2021
Scalable golang ratelimiter using the sliding window algorithm. Currently supports only Redis.

go-ratelimiter Scalable golang ratelimiter using the sliding window algorithm. Currently supports only Redis. Example usage client := redis.NewClient

null 0 Oct 19, 2021
Clean-Swift source and test code auto-generator. It can save you time typing 500-600 lines of code.

Clean-Swift source & test code auto generator Overview Run Output Basic Usage make config.yaml target_project_name: Miro // target project name copyri

David Ha 20 Apr 13, 2022
Versatile Go code generator.

Generis Versatile Go code generator. Description Generis is a lightweight code preprocessor adding the following features to the Go language : Generic

SenseLogic 37 Nov 30, 2022
An enum generator for go

go-enum An enum generator for go How it works The goal of go-enum is to create an easy to use enum generator that will take a decorated type declarati

Alex Bice 412 Dec 2, 2022
Jennifer is a code generator for Go

Jennifer Jennifer is a code generator for Go. package main import ( "fmt" . "github.com/dave/jennifer/jen" ) func main() { f := NewFile("m

Dave Brophy 2.6k Dec 2, 2022
Galvanity is Algorand vanity address generator written in Go

Galvanity Galvanity is Algorand vanity address generator written in Go Usage galvanity [search-type] <pattern> search-type is matching function to sea

Sherzod Mutalov 7 Nov 14, 2022
xgen generator with extend features

XGen Plus Generator Introduction xgen is a library written in pure Go providing a set of functions that allow you to parse XSD (XML schema definition)

ZaharovII 0 Dec 8, 2021
Color generator with golang

color-generator How to use this repo <img src="https://color-pallete-gen.herokuapp.com/hexCode" /> Like this: Getting Started Copy sample.env to .env

João Marcus Fernandes 0 Oct 22, 2021
Rest Api Generator for Golang Programming Language

Rest Api Generator for Golang Programming Language

Eko Kurniadi 3 Nov 29, 2021