2021 day8/rust: speed up v3 to unsafe levels, remove v4
This commit is contained in:
parent
07a1391030
commit
daec76d3d4
5 changed files with 5 additions and 84 deletions
|
@ -1,7 +1,7 @@
|
|||
use std::{fs, path::PathBuf};
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use day8_rs::{v1, v2, v3, v4};
|
||||
use day8_rs::{v1, v2, v3};
|
||||
|
||||
pub fn criterion_benchmark(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("unscramble");
|
||||
|
@ -33,13 +33,6 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
}
|
||||
})
|
||||
});
|
||||
group.bench_function("v4", |b| {
|
||||
b.iter(|| {
|
||||
for line in &lines {
|
||||
let _ = unsafe { v4::unscramble(black_box(line)) };
|
||||
}
|
||||
})
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,4 +10,3 @@ pub struct LineResult {
|
|||
pub mod v1;
|
||||
pub mod v2;
|
||||
pub mod v3;
|
||||
pub mod v4;
|
||||
|
|
|
@ -50,9 +50,10 @@ pub fn unscramble(line: &str) -> LineResult {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Some(c) => {
|
||||
Some(c @ b'a'..=b'g') => {
|
||||
freq += counts[c as usize - b'a' as usize];
|
||||
}
|
||||
},
|
||||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
use crate::LineResult;
|
||||
|
||||
const FREQ_TABLE: [usize; 256] = {
|
||||
let mut tab = [0; 256];
|
||||
tab[17] = 1;
|
||||
tab[25] = 7;
|
||||
tab[30] = 4;
|
||||
tab[34] = 2;
|
||||
tab[37] = 5;
|
||||
tab[39] = 3;
|
||||
tab[41] = 6;
|
||||
tab[42] = 0;
|
||||
tab[45] = 9;
|
||||
tab[49] = 8;
|
||||
tab
|
||||
};
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub unsafe fn unscramble(line: &str) -> LineResult {
|
||||
let mut bytes = line.bytes();
|
||||
|
||||
let mut counts = [0; 7];
|
||||
loop {
|
||||
match bytes.next().unwrap() {
|
||||
c @ b'a'..=b'g' => {
|
||||
*unsafe { counts.get_unchecked_mut(c as usize - b'a' as usize) } += 1;
|
||||
}
|
||||
b'|' => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
bytes.next();
|
||||
|
||||
let mut freq = 0;
|
||||
let mut unique_digits = 0;
|
||||
let mut number = 0;
|
||||
loop {
|
||||
let c = bytes.next();
|
||||
match c {
|
||||
Some(b' ') | None => {
|
||||
let digit = FREQ_TABLE[freq & 0xff];
|
||||
if [1, 4, 7, 8].contains(&digit) {
|
||||
unique_digits += 1;
|
||||
}
|
||||
number = number * 10 + digit;
|
||||
freq = 0;
|
||||
if c.is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Some(c) => {
|
||||
freq += unsafe { counts.get_unchecked(c as usize - b'a' as usize) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LineResult {
|
||||
unique_digits,
|
||||
number,
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use day8_rs::{v1, v2, v3, v4, LineResult};
|
||||
use day8_rs::{v1, v2, v3, LineResult};
|
||||
|
||||
fn test_unscramble_with_input(f: fn(&str) -> LineResult, input: &[&str]) -> LineResult {
|
||||
let mut result = LineResult {
|
||||
|
@ -70,12 +70,3 @@ pub fn test_unscramble_v2() {
|
|||
pub fn test_unscramble_v3() {
|
||||
test_unscramble(v3::unscramble)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_unscramble_v4() {
|
||||
fn safe_v4(input: &str) -> LineResult {
|
||||
unsafe { v4::unscramble(input) }
|
||||
}
|
||||
|
||||
test_unscramble(safe_v4)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue