{"id":37143177,"url":"https://github.com/cafxx/fastrand","last_synced_at":"2026-01-14T16:48:23.588Z","repository":{"id":57560267,"uuid":"326179512","full_name":"CAFxX/fastrand","owner":"CAFxX","description":"Fast, concurrent PRNGs","archived":false,"fork":false,"pushed_at":"2022-09-28T13:47:30.000Z","size":69,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-20T09:12:10.457Z","etag":null,"topics":["atomic","concurrency","golang","lock-free","pcg","pcg-random","performance","prng","random","random-number-generators","splitmix","xoshiro256"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CAFxX.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-02T12:36:27.000Z","updated_at":"2022-10-07T16:50:09.000Z","dependencies_parsed_at":"2022-08-26T07:02:16.042Z","dependency_job_id":null,"html_url":"https://github.com/CAFxX/fastrand","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/CAFxX/fastrand","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAFxX%2Ffastrand","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAFxX%2Ffastrand/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAFxX%2Ffastrand/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAFxX%2Ffastrand/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CAFxX","download_url":"https://codeload.github.com/CAFxX/fastrand/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAFxX%2Ffastrand/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28426481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T16:38:47.836Z","status":"ssl_error","status_checked_at":"2026-01-14T16:34:59.695Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic","concurrency","golang","lock-free","pcg","pcg-random","performance","prng","random","random-number-generators","splitmix","xoshiro256"],"created_at":"2026-01-14T16:48:22.826Z","updated_at":"2026-01-14T16:48:23.583Z","avatar_url":"https://github.com/CAFxX.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastrand\n\n[![Build status](https://github.com/CAFxX/fastrand/workflows/Build/badge.svg)](https://github.com/CAFxX/fastrand/actions)\n[![codecov](https://codecov.io/gh/CAFxX/fastrand/branch/main/graph/badge.svg)](https://codecov.io/gh/CAFxX/fastrand)\n[![Go Report](https://goreportcard.com/badge/github.com/CAFxX/fastrand)](https://goreportcard.com/report/github.com/CAFxX/fastrand) \n[![Go Reference](https://pkg.go.dev/badge/github.com/CAFxX/fastrand.svg)](https://pkg.go.dev/github.com/CAFxX/fastrand) :warning: API is not stable yet.\n\nSome fast, non-cryptographic PRNG sources, in three variants:\n\n- **Plain** - the basic implementation. Fastest, but can not be used concurrently without external synchronization.\n- **Atomic** - implementation using atomic operations. Non-locking, can be used concurrently, but a bit slower (especially at high concurrency).\n- **Sharded** - implementation using per-thread (P) sharding. Non-locking, can be used concurrently, fast (even at high concurrency), but does not support explicit seeding.\n\nPRNGs currently implemented:\n\n| Name                                                         | State (bits) | Output (bits) | Period            | Variants               |\n| ------------------------------------------------------------ | ------------ | ------------- | ----------------- | ---------------------- |\n| [SplitMix64](https://dl.acm.org/doi/10.1145/2714064.2660195) | 64           | 64            | 2\u003csup\u003e64\u003c/sup\u003e    | Plain, Atomic, Sharded |\n| [PCG-XSH-RR](https://www.pcg-random.org/)                    | 64           | 32            | 2\u003csup\u003e64\u003c/sup\u003e    | Plain, Atomic, Sharded |\n| [Xoshiro256**](http://prng.di.unimi.it/)                     | 256          | 64            | 2\u003csup\u003e256\u003c/sup\u003e-1 | Plain, Sharded         |\n\nPlanned additions include:\n\n| Name                                      | State (bits) | Output (bits) | Period            | Variants                           |\n| ----------------------------------------- | ------------ | ------------- | ----------------- | ---------------------------------- |\n| [PCG-XSL-RR](https://www.pcg-random.org/) | 128          | 64            | 2\u003csup\u003e128\u003c/sup\u003e   | Plain, Atomic\u003csup\u003e3\u003c/sup\u003e, Sharded |\n| [xorshift128+](http://prng.di.unimi.it/)  | 128          | 64            | 2\u003csup\u003e128\u003c/sup\u003e-1 | Plain, Atomic\u003csup\u003e3\u003c/sup\u003e, Sharded |\n\n## Performance\n\nTests run on a `Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz` with Turbo Boost disabled. Lower is better.\n\n### `GOMAXPROCS=1`\n\n| PRNG         |  Plain |              Atomic | Sharded |\n| ------------ | -----: | ------------------: | ------: |\n| SplitMix64   | 2.02ns |              8.72ns |  7.33ns |\n| PCG-XSH-RR   | 3.17ns |             11.90ns |  7.33ns |\n| Xoshiro256** | 4.57ns |       -\u003csup\u003e1\u003c/sup\u003e | 12.40ns |\n| math/rand    | 7.06ns | 24.20ns\u003csup\u003e2\u003c/sup\u003e |       - |\n\n### `GOMAXPROCS=8`\n\n| PRNG         |  Plain |              Atomic | Sharded |\n| ------------ | -----: | ------------------: | ------: |\n| SplitMix64   | 0.29ns |             26.20ns |  1.33ns |\n| PCG-XSH-RR   | 0.41ns |             13.20ns |  1.34ns |\n| Xoshiro256** | 0.81ns |       -\u003csup\u003e1\u003c/sup\u003e |  2.12ns |\n| math/rand    | 1.19ns | 72.40ns\u003csup\u003e2\u003c/sup\u003e |       - |\n\n## Usage notes\n\n### Atomic variants\n\nThe atomic variant currently relies on `unsafe` to improve the performance of its CAS loops. It does so by calling the unexported `procyield` function in package `runtime`. This dependency will be removed in a future release. Usage of `unsafe` can be disabled by setting the `fastrand_nounsafe` build tag, at the cost of lower performance.\n\nThe state of the atomic variants is not padded/aligned to fill the cacheline: if needed users should pad the structure to avoid false sharing of the cacheline.\n\n### Sharded variants\n\nSharded variants rely on `unsafe` to implement sharding. They do so by calling the unexported `procPin` and `procUnpin` functions in package `runtime`. These functions are used by other packages (e.g. `sync`) for the same purpose, so they are unlikely to disappear/change. Usage of `unsafe` can be disabled by setting the `fastrand_nounsafe` build tag, at the cost of lower performance.\n\nSharded variants detect the value of `GOMAXPROCS` when they are instantiated (with `NewShardedXxx`). If `GOMAXPROCS` is increased after a sharded PRNG is instantiated it will yield suboptimal performance, as it may dynamically fallback to the corresponding atomic variant.\n\nSharded variants use more memory for the state than the other variants: in general they use at least `GOMAXPROCS * 64` bytes. This is done to avoid false sharing of cachelines between shards.\n\nSharded variants do not allow explicit seeding since there is no easy way for a user to obtain a deterministic sequence from these variants (because, in general, goroutines can migrate between threads at any time).\n\n## License\n\n[MIT](LICENSE)\n\n---\n\n\u003csup\u003e1\u003c/sup\u003e there is no atomic variant for Xoshiro256** because its large state is not amenable to a performant atomic implementation.\n\n\u003csup\u003e2\u003c/sup\u003e the `math/rand` atomic variant is not a pure non-locking implementation, since it is implemented by guarding a `rand.Rand` using a `sync.Mutex`.\n\n\u003csup\u003e3\u003c/sup\u003e only for platforms where 128 bit CAS primitives are supported.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcafxx%2Ffastrand","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcafxx%2Ffastrand","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcafxx%2Ffastrand/lists"}