aboutsummaryrefslogtreecommitdiff
path: root/nix-rust
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-12-10 19:50:02 +0100
committerEelco Dolstra <edolstra@gmail.com>2019-12-10 22:06:05 +0100
commitf64b58b45e86e15f64aa2dff67436c2d6fe4a4d8 (patch)
treedf139b5452f6ff66804795ea367394c48fc39bd0 /nix-rust
parentbbe97dff8b3054d96e758f486f9ce3fa09e64de3 (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')
-rw-r--r--nix-rust/src/util/base32.rs26
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);