factor::Decomposition: Inline a small number (4) of factors

This avoids allocating on the heap when factoring most numbers,
without using much space on the stack.

This is ~3.5% faster than the previous commit, and ~8.3% faster than “master”.
This commit is contained in:
nicoo 2020-07-29 20:51:05 +02:00 committed by Roy Ivy III
parent 78ae0cca31
commit 0d39732300
3 changed files with 16 additions and 2 deletions

7
Cargo.lock generated
View file

@ -1243,6 +1243,11 @@ dependencies = [
"generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
@ -1639,6 +1644,7 @@ dependencies = [
"quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)",
"uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)",
]
@ -2682,6 +2688,7 @@ dependencies = [
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"
"checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0"
"checksum smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"

View file

@ -18,6 +18,7 @@ num-traits = "0.2" # used in src/numerics.rs, which is included by build.rs
[dependencies]
num-traits = "0.2"
rand = { version="0.7", features=["small_rng"] }
smallvec = { version="0.6.13, < 1.0" }
uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" }
uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" }

View file

@ -7,6 +7,7 @@
extern crate rand;
use smallvec::SmallVec;
use std::cell::RefCell;
use std::fmt;
@ -16,11 +17,16 @@ use crate::{miller_rabin, rho, table};
type Exponent = u8;
#[derive(Clone, Debug)]
struct Decomposition(Vec<(u64, Exponent)>);
struct Decomposition(SmallVec<[(u64, Exponent); NUM_FACTORS_INLINE]>);
// The number of factors to inline directly into a `Decomposition` object.
// As a consequence of the ErdősKac theorem, the average number of prime
// factors of integers < 10²⁵ ≃ 2⁸³ is 4, so we can use that value.
const NUM_FACTORS_INLINE: usize = 4;
impl Decomposition {
fn one() -> Decomposition {
Decomposition(Vec::new())
Decomposition(SmallVec::new())
}
fn add(&mut self, factor: u64, exp: Exponent) {