mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
Merge pull request #2746 from rivy/fix.factor
fix/factor ~ minor repairs to docs and tests
This commit is contained in:
commit
00769af807
2 changed files with 9 additions and 6 deletions
|
@ -44,7 +44,8 @@ on Daniel Lemire's [*Microbenchmarking calls for idealized conditions*][lemire],
|
||||||
which I recommend reading if you want to add benchmarks to `factor`.
|
which I recommend reading if you want to add benchmarks to `factor`.
|
||||||
|
|
||||||
1. Select a small, self-contained, deterministic component
|
1. Select a small, self-contained, deterministic component
|
||||||
`gcd` and `table::factor` are good example of such:
|
(`gcd` and `table::factor` are good examples):
|
||||||
|
|
||||||
- no I/O or access to external data structures ;
|
- no I/O or access to external data structures ;
|
||||||
- no call into other components ;
|
- no call into other components ;
|
||||||
- behavior is deterministic: no RNG, no concurrency, ... ;
|
- behavior is deterministic: no RNG, no concurrency, ... ;
|
||||||
|
@ -53,16 +54,19 @@ which I recommend reading if you want to add benchmarks to `factor`.
|
||||||
maximizing the numbers of samples we can take in a given time.
|
maximizing the numbers of samples we can take in a given time.
|
||||||
|
|
||||||
2. Benchmarks are immutable (once merged in `uutils`)
|
2. Benchmarks are immutable (once merged in `uutils`)
|
||||||
|
|
||||||
Modifying a benchmark means previously-collected values cannot meaningfully
|
Modifying a benchmark means previously-collected values cannot meaningfully
|
||||||
be compared, silently giving nonsensical results. If you must modify an
|
be compared, silently giving nonsensical results. If you must modify an
|
||||||
existing benchmark, rename it.
|
existing benchmark, rename it.
|
||||||
|
|
||||||
3. Test common cases
|
3. Test common cases
|
||||||
|
|
||||||
We are interested in overall performance, rather than specific edge-cases;
|
We are interested in overall performance, rather than specific edge-cases;
|
||||||
use **reproducibly-randomized inputs**, sampling from either all possible
|
use **reproducibly-randomized inputs**, sampling from either all possible
|
||||||
input values or some subset of interest.
|
input values or some subset of interest.
|
||||||
|
|
||||||
4. Use [`criterion`], `criterion::black_box`, ...
|
4. Use [`criterion`], `criterion::black_box`, ...
|
||||||
|
|
||||||
`criterion` isn't perfect, but it is also much better than ad-hoc
|
`criterion` isn't perfect, but it is also much better than ad-hoc
|
||||||
solutions in each benchmark.
|
solutions in each benchmark.
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub fn gcd(mut u: u64, mut v: u64) -> u64 {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use quickcheck::quickcheck;
|
use quickcheck::{quickcheck, TestResult};
|
||||||
|
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
fn euclidean(a: u64, b: u64) -> bool {
|
fn euclidean(a: u64, b: u64) -> bool {
|
||||||
|
@ -76,13 +76,12 @@ mod tests {
|
||||||
gcd(0, a) == a
|
gcd(0, a) == a
|
||||||
}
|
}
|
||||||
|
|
||||||
fn divisor(a: u64, b: u64) -> () {
|
fn divisor(a: u64, b: u64) -> TestResult {
|
||||||
// Test that gcd(a, b) divides a and b, unless a == b == 0
|
// Test that gcd(a, b) divides a and b, unless a == b == 0
|
||||||
if a == 0 && b == 0 { return; }
|
if a == 0 && b == 0 { return TestResult::discard(); } // restrict test domain to !(a == b == 0)
|
||||||
|
|
||||||
let g = gcd(a, b);
|
let g = gcd(a, b);
|
||||||
assert_eq!(a % g, 0);
|
TestResult::from_bool( g != 0 && a % g == 0 && b % g == 0 )
|
||||||
assert_eq!(b % g, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commutative(a: u64, b: u64) -> bool {
|
fn commutative(a: u64, b: u64) -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue