Skip to content

Commit

Permalink
docs: Improve documentation; update benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
aspen committed Dec 3, 2020
1 parent 8747735 commit e78572c
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 49 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ randomize = "^3.0"
oorandom = "^11.1"
rand_core = "^0.5"
rand_pcg = "^0.2"
rand_chacha = "^0.2"
random-fast-rng = "^0.1"
fastrand = "^1.4"
wyhash = "^0.4"
hex = "^0.4"

[[bench]]
name = "randbench"
name = "speed"
harness = false

[profile.bench]
Expand Down
51 changes: 27 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,30 @@ A library meant for fast, random number generation with quick compile time, and
```rust
use nanorand::{RNG, WyRand};

fn main() {
let mut rng = WyRand::new();
println!("Random number: {}", rng.generate::<u64>());
}
let mut rng = WyRand::new();
println!("Random number: {}", rng.generate::<u64>());
```
### Generating a number with a thread-local RNG
```rust
use nanorand::RNG;

fn main() {
let mut rng = nanorand::tls_rng();
println!("Random number: {}", rng.generate::<u64>());
}
let mut rng = nanorand::tls_rng();
println!("Random number: {}", rng.generate::<u64>());
```
### Generating a number in a range
```rust
use nanorand::{RNG, WyRand};

fn main() {
let mut rng = WyRand::new();
println!("Random number between 1 and 100: {}", rng.generate_range::<u64>(1, 100));
}
let mut rng = WyRand::new();
println!("Random number between 1 and 100: {}", rng.generate_range::<u64>(1, 100));
```
### Shuffling a Vec
```rust
use nanorand::{RNG, WyRand};

fn main() {
let mut rng = WyRand::new();
let mut items = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
rng.shuffle(&mut items);
}
let mut rng = WyRand::new();
let mut items = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
rng.shuffle(&mut items);
```

### Why should I use this over...
Expand All @@ -53,16 +45,27 @@ fn main() {

### RNG Implementations

**RNG**|**nanorand type**|**Output Size**|**Cryptographically Secure**|**Speed**|**Notes**|**Original Implementation**
**RNG**|**nanorand type**|**Output Size**|**Cryptographically Secure**|**Speed**<sup>1</sup>|**Notes**|**Original Implementation**
:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:
wyrand|[nanohash::WyRand](rand/wyrand/struct.WyRand.html)|64 bits (`u64`)|🚫|4 GB/s||https://github.com/lemire/testingRNG/blob/master/source/wyrand.h
Pcg64|[nanohash::Pcg64](rand/pcg64/struct.Pcg64.html)|64 bits (`u64`)|🚫|1 GB/s||https://github.com/rkern/pcg64
ChaCha|[nanohash::ChaCha](rand/chacha/struct.ChaCha.html)|512 bits (`[u32; 16]`)|✅|90 MB/s (ChaCha8), 40 MB/s (ChaCha20)|Currently only works in **Nightly** Rust, will work with Stable 1.47 (see [rust#74060](https://github.com/rust-lang/rust/pull/74060))|https://cr.yp.to/chacha.html
wyrand|[nanorand::WyRand](rand/wyrand/struct.WyRand.html), [nanorand::tls::TlsWyRand](tls/fn.tls_rng.html)|64 bits (`u64`)|🚫|8.6 GB/s||[https://github.com/lemire/testingRNG/blob/master/source/wyrand.h](https://github.com/lemire/testingRNG/blob/master/source/wyrand.h)
Pcg64|[nanorand::Pcg64](rand/pcg64/struct.Pcg64.html)|64 bits (`u64`)|🚫|2.3 GB/s||[https://github.com/rkern/pcg64](https://github.com/rkern/pcg64)
ChaCha|[nanorand::ChaCha](rand/chacha/struct.ChaCha.html)|512 bits (`[u32; 16]`)|✅|140 MB/s (ChaCha8), 70 MB/s (ChaCha20)|Only works in Rust 1.47 or above|[https://cr.yp.to/chacha.html](https://cr.yp.to/chacha.html)

### Entropy Sources
<sup>1. Speed benchmarked on an Intel Core i7 8086k processor running at 5.1 GHz</sup>

* Unix-like (Linux, Android, macOS, iOS, FreeBSD, OpenBSD) - first `/dev/urandom`, else `/dev/random`, else system time.
* Windows - `BCryptGenRandom` with system-preferred RNG.
### Entropy Sources
_Listed in order of priority_

* If the `getrandom` feature is enabled, then [getrandom::getrandom](https://docs.rs/getrandom/*/getrandom/fn.getrandom.html) will be called.
* If the `rdseed` feature is enabled, and is running on an x86(-64) system with the [RDSEED](https://en.wikipedia.org/wiki/RDRAND) instruction, then
we will attempt to source as much entropy as possible via our [rdseed_entropy](entropy::rdseed_entropy) function
* Unix-like systems (Linux, macOS, iOS, BSD, Android)
* We will first attempt to source random bytes from [`/dev/urandom`](https://linux.die.net/man/4/urandom)
* If that fails, we will resort to [`/dev/random`](https://linux.die.net/man/4/random)
* Windows
* If we're targeting UWP, then the [`BCryptGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom) is used with system-preferred RNG (`BCRYPT_USE_SYSTEM_PREFERRED_RNG`).
* Otherwise, we'll use [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom).
* If all else fails, and the `std` feature is enabled, we'll resort to pulling bytes from the current system unix time ([entropy::emergency_system_time_entropy]), and screwing with them via XOR and endianness operations.

### Feature Flags

Expand Down
File renamed without changes.
49 changes: 26 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,30 @@
//! ```rust
//! use nanorand::{RNG, WyRand};
//!
//! fn main() {
//! let mut rng = WyRand::new();
//! println!("Random number: {}", rng.generate::<u64>());
//! }
//! let mut rng = WyRand::new();
//! println!("Random number: {}", rng.generate::<u64>());
//! ```
//! ## Generating a number with a thread-local RNG
//! ```rust
//! use nanorand::RNG;
//!
//! fn main() {
//! let mut rng = nanorand::tls_rng();
//! println!("Random number: {}", rng.generate::<u64>());
//! }
//! let mut rng = nanorand::tls_rng();
//! println!("Random number: {}", rng.generate::<u64>());
//! ```
//! ## Generating a number in a range
//! ```rust
//! use nanorand::{RNG, WyRand};
//!
//! fn main() {
//! let mut rng = WyRand::new();
//! println!("Random number between 1 and 100: {}", rng.generate_range::<u64>(1, 100));
//! }
//! let mut rng = WyRand::new();
//! println!("Random number between 1 and 100: {}", rng.generate_range::<u64>(1, 100));
//! ```
//! ## Shuffling a Vec
//! ```rust
//! use nanorand::{RNG, WyRand};
//!
//! fn main() {
//! let mut rng = WyRand::new();
//! let mut items = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
//! rng.shuffle(&mut items);
//! }
//! let mut rng = WyRand::new();
//! let mut items = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
//! rng.shuffle(&mut items);
//! ```
//!
//! ## Why should I use this over...
Expand All @@ -50,16 +42,27 @@
//!
//! ## RNG Implementations
//!
//! **RNG**|**nanorand type**|**Output Size**|**Cryptographically Secure**|**Speed**|**Notes**|**Original Implementation**
//! **RNG**|**nanorand type**|**Output Size**|**Cryptographically Secure**|**Speed**<sup>1</sup>|**Notes**|**Original Implementation**
//! :-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:
//! wyrand|[nanohash::WyRand](rand/wyrand/struct.WyRand.html)|64 bits (`u64`)|🚫|4 GB/s||https://github.com/lemire/testingRNG/blob/master/source/wyrand.h
//! Pcg64|[nanohash::Pcg64](rand/pcg64/struct.Pcg64.html)|64 bits (`u64`)|🚫|1 GB/s||https://github.com/rkern/pcg64
//! ChaCha|[nanohash::ChaCha](rand/chacha/struct.ChaCha.html)|512 bits (`[u32; 16]`)|✅|90 MB/s (ChaCha8), 40 MB/s (ChaCha20)|Currently only works in **Nightly** Rust, will work with Stable 1.47 (see [rust#74060](https://github.com/rust-lang/rust/pull/74060))|https://cr.yp.to/chacha.html
//! wyrand|[nanorand::WyRand](rand/wyrand/struct.WyRand.html), [nanorand::tls::TlsWyRand](tls/fn.tls_rng.html)|64 bits (`u64`)|🚫|8.6 GB/s||[https://github.com/lemire/testingRNG/blob/master/source/wyrand.h](https://github.com/lemire/testingRNG/blob/master/source/wyrand.h)
//! Pcg64|[nanorand::Pcg64](rand/pcg64/struct.Pcg64.html)|64 bits (`u64`)|🚫|2.3 GB/s||[https://github.com/rkern/pcg64](https://github.com/rkern/pcg64)
//! ChaCha|[nanorand::ChaCha](rand/chacha/struct.ChaCha.html)|512 bits (`[u32; 16]`)|✅|140 MB/s (ChaCha8), 70 MB/s (ChaCha20)|Only works in Rust 1.47 or above|[https://cr.yp.to/chacha.html](https://cr.yp.to/chacha.html)
//!
//! <sup>1. Speed benchmarked on an Intel Core i7 8086k processor running at 5.1 GHz</sup>
//!
//! ## Entropy Sources
//! _Listed in order of priority_
//!
//! * Unix-like (Linux, Android, macOS, iOS, FreeBSD, OpenBSD) - first `/dev/urandom`, else `/dev/random`, else system time.
//! * Windows - `BCryptGenRandom` with system-preferred RNG.
//! * If the `getrandom` feature is enabled, then [getrandom::getrandom](https://docs.rs/getrandom/*/getrandom/fn.getrandom.html) will be called.
//! * If the `rdseed` feature is enabled, and is running on an x86(-64) system with the [RDSEED](https://en.wikipedia.org/wiki/RDRAND) instruction, then
//! we will attempt to source as much entropy as possible via our [rdseed_entropy](entropy::rdseed_entropy) function
//! * Unix-like systems (Linux, macOS, iOS, BSD, Android)
//! * We will first attempt to source random bytes from [`/dev/urandom`](https://linux.die.net/man/4/urandom)
//! * If that fails, we will resort to [`/dev/random`](https://linux.die.net/man/4/random)
//! * Windows
//! * If we're targeting UWP, then the [`BCryptGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom) is used with system-preferred RNG (`BCRYPT_USE_SYSTEM_PREFERRED_RNG`).
//! * Otherwise, we'll use [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom).
//! * If all else fails, and the `std` feature is enabled, we'll resort to pulling bytes from the current system unix time ([entropy::emergency_system_time_entropy]), and screwing with them via XOR and endianness operations.
//!
//! ## Feature Flags
//!
Expand Down
1 change: 0 additions & 1 deletion src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ impl DerefMut for TlsWyRand {
/// std::thread::spawn(move || {
/// println!("Random number: {}", rng.generate::<u64>());
/// });
/// }
/// ```
pub fn tls_rng() -> TlsWyRand {
WYRAND.with(|tls| TlsWyRand(tls.get()))
Expand Down

0 comments on commit e78572c

Please sign in to comment.