Skip to content

Instantly share code, notes, and snippets.

@orlp
Created March 4, 2023 14:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orlp/fdc27b86e658c3b6df709c68ab477a14 to your computer and use it in GitHub Desktop.
Save orlp/fdc27b86e658c3b6df709c68ab477a14 to your computer and use it in GitHub Desktop.
use std::collections::HashMap;
use rand::{Rng, seq::SliceRandom};
use std::time::Instant;
fn rand_input(rng: &mut impl Rng) -> String {
let theirs = ["A", "B", "C"].choose(rng).unwrap();
let ours = ["X", "Y", "Z"].choose(rng).unwrap();
format!("{theirs} {ours}\n")
}
const LUT: [u8; 16] = [7, 1, 4, 2, 5, 8, 6, 9, 3,
0, 0, 0, 0, 0, 0, 0];
fn phf_lut(x: u32) -> u8 {
LUT[(x.wrapping_mul(0xedc72f12) >> 28) as usize]
}
fn phf_shift(x: u32) -> u8 {
let shift = x.wrapping_mul(0xa463293e) >> 27;
((0x824a1847u32 >> shift) & 0b11111) as u8
}
fn main() {
let str_answers = HashMap::from([
("A X", 4u8),
("A Y", 8),
("A Z", 3),
("B X", 1),
("B Y", 5),
("B Z", 9),
("C X", 7),
("C Y", 2),
("C Z", 6),
]);
let u32_answers = HashMap::from([
(0xa582041_u32, 4u8),
(0xa592041, 8),
(0xa5a2041, 3),
(0xa582042, 1),
(0xa592042, 5),
(0xa5a2042, 9),
(0xa582043, 7),
(0xa592043, 2),
(0xa5a2043, 6),
]);
let mut rng = rand::thread_rng();
let repeats = 10;
let size = 10_000_000;
let test_input: String = (0..size).map(|_| rand_input(&mut rng)).collect();
{
let start = Instant::now();
let mut res: u64 = 0;
for _ in 0..repeats {
res += test_input.lines().map(|s| str_answers[s] as u64).sum::<u64>();
}
println!("hashmap_str {res} {:?}", start.elapsed() / repeats);
}
{
let start = Instant::now();
let mut res: u64 = 0;
for _ in 0..repeats {
res += test_input.as_bytes().chunks_exact(4).map(|s| {
u32_answers[&u32::from_le_bytes(s.try_into().unwrap())] as u64
}).sum::<u64>();
}
println!("hashmap_u32 {res} {:?}", start.elapsed() / repeats);
}
{
let start = Instant::now();
let mut res: u64 = 0;
for _ in 0..repeats {
res += test_input.as_bytes().chunks_exact(4).map(|s| {
phf_lut(u32::from_le_bytes(s.try_into().unwrap())) as u64
}).sum::<u64>();
}
println!("phf_lut {res} {:?}", start.elapsed() / repeats);
}
{
let start = Instant::now();
let mut res: u64 = 0;
for _ in 0..repeats {
res += test_input.as_bytes().chunks_exact(4).map(|s| {
phf_shift(u32::from_le_bytes(s.try_into().unwrap())) as u64
}).sum::<u64>();
}
println!("phf_shift {res} {:?}", start.elapsed() / repeats);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment