From 0d39732300332e15dd0b1a87b351b0971cfada57 Mon Sep 17 00:00:00 2001 From: nicoo Date: Wed, 29 Jul 2020 20:51:05 +0200 Subject: [PATCH] factor::Decomposition: Inline a small number (4) of factors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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”. --- Cargo.lock | 7 +++++++ src/uu/factor/Cargo.toml | 1 + src/uu/factor/src/factor.rs | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b54012e6..74216eefa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index c4dbc96cc..a37ee5249 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -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" } diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index f6da886a1..b6a38ab79 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -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ős–Kac 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) {