diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-12-10 19:50:02 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-12-10 22:06:05 +0100 |
commit | f64b58b45e86e15f64aa2dff67436c2d6fe4a4d8 (patch) | |
tree | df139b5452f6ff66804795ea367394c48fc39bd0 /nix-rust/src | |
parent | bbe97dff8b3054d96e758f486f9ce3fa09e64de3 (diff) |
Speed up base32::decode()
From 1.03% to 0.19% of the runtime of 'nix-instantiate "<nixpkgs>" -A
texlive.combined.scheme-full --dry-run'.
Diffstat (limited to 'nix-rust/src')
-rw-r--r-- | nix-rust/src/util/base32.rs | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/nix-rust/src/util/base32.rs b/nix-rust/src/util/base32.rs index ee42a0362..8f6410f16 100644 --- a/nix-rust/src/util/base32.rs +++ b/nix-rust/src/util/base32.rs @@ -1,5 +1,4 @@ use crate::error::Error; -use std::collections::HashMap; pub fn encoded_len(input_len: usize) -> usize { if input_len == 0 { @@ -9,14 +8,20 @@ pub fn encoded_len(input_len: usize) -> usize { } } +pub fn decoded_len(input_len: usize) -> usize { + input_len * 5 / 8 +} + static BASE32_CHARS: &'static [u8; 32] = &b"0123456789abcdfghijklmnpqrsvwxyz"; lazy_static! { - static ref BASE32_CHARS_REVERSE: HashMap<char, u8> = BASE32_CHARS - .iter() - .enumerate() - .map(|(n, c)| (*c as char, n as u8)) - .collect(); + static ref BASE32_CHARS_REVERSE: Box<[u8; 256]> = { + let mut xs = [0xffu8; 256]; + for (n, c) in BASE32_CHARS.iter().enumerate() { + xs[*c as usize] = n as u8; + } + Box::new(xs) + }; } pub fn encode(input: &[u8]) -> String { @@ -44,14 +49,17 @@ pub fn encode(input: &[u8]) -> String { } pub fn decode(input: &str) -> Result<Vec<u8>, crate::Error> { - let mut res = Vec::new(); + let mut res = Vec::with_capacity(decoded_len(input.len())); let mut nr_bits_left: usize = 0; let mut bits_left: u16 = 0; for c in input.chars().rev() { - let x = BASE32_CHARS_REVERSE.get(&c).ok_or(Error::BadBase32)?; - bits_left |= (*x as u16) << nr_bits_left; + let b = BASE32_CHARS_REVERSE[c as usize]; + if b == 0xff { + return Err(Error::BadBase32); + } + bits_left |= (b as u16) << nr_bits_left; nr_bits_left += 5; if nr_bits_left >= 8 { res.push((bits_left & 0xff) as u8); |