Faster hash set

This commit is contained in:
2022-12-09 11:43:33 +01:00
parent a44420cbe7
commit e45aaad1c4
3 changed files with 19 additions and 24 deletions

View File

@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
ahash = "0.8.2"
anyhow = "1.0.66" anyhow = "1.0.66"
clap = { version = "4.0.19", features = ["derive"] } clap = { version = "4.0.19", features = ["derive"] }
itertools = "0.10.5" itertools = "0.10.5"

View File

@@ -10,34 +10,31 @@ use criterion::Criterion;
/// Number of days we have an implementation to benchmark /// Number of days we have an implementation to benchmark
const DAYS_IMPLEMENTED: u8 = 25; const DAYS_IMPLEMENTED: u8 = 25;
fn read_input(day: u8) -> Vec<u8> { fn read_input(day: u8) -> std::io::Result<Vec<u8>> {
let input_path = format!("inputs/{:02}.txt", day); let input_path = format!("inputs/{:02}.txt", day);
let mut buffer = Vec::new(); let mut buffer = Vec::new();
File::open(input_path) File::open(input_path)?.read_to_end(&mut buffer)?;
.expect("Failed to open input file")
.read_to_end(&mut buffer)
.expect("Failed to read input file");
buffer Ok(buffer)
} }
pub fn benchmark_days(c: &mut Criterion) { pub fn benchmark_days(c: &mut Criterion) {
for day in 1..=DAYS_IMPLEMENTED { for day in 1..=DAYS_IMPLEMENTED {
let input = read_input(day); if let Ok(input) = read_input(day) {
let part1 = get_implementation(day, false).unwrap();
let part1 = get_implementation(day, false).unwrap(); c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
b.iter(|| part1(i));
c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
b.iter(|| part1(i));
});
if day < 25 {
let part2 = get_implementation(day, true).unwrap();
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
b.iter(|| part2(i));
}); });
if day < 25 {
let part2 = get_implementation(day, true).unwrap();
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
b.iter(|| part2(i));
});
}
} }
} }
} }

View File

@@ -1,9 +1,9 @@
use std::collections::HashSet;
use std::ops::Add; use std::ops::Add;
use std::ops::Index; use std::ops::Index;
use std::ops::IndexMut; use std::ops::IndexMut;
use std::ops::Sub; use std::ops::Sub;
use ahash::AHashSet;
use anyhow::Result; use anyhow::Result;
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::bytes::complete::take; use nom::bytes::complete::take;
@@ -101,7 +101,7 @@ fn part_generic<const N: usize>(input: &[u8]) -> Result<String> {
let mut head_pos = Vec2([0, 0]); let mut head_pos = Vec2([0, 0]);
let mut tails = [head_pos; N]; let mut tails = [head_pos; N];
let mut visited = HashSet::new(); let mut visited = AHashSet::new();
visited.insert(head_pos); visited.insert(head_pos);
for (direction, steps) in moves { for (direction, steps) in moves {
@@ -112,7 +112,7 @@ fn part_generic<const N: usize>(input: &[u8]) -> Result<String> {
let mut ref_pos = head_pos; let mut ref_pos = head_pos;
for (i, tail_pos) in tails.iter_mut().enumerate() { for tail_pos in &mut tails {
let delta = ref_pos - *tail_pos; let delta = ref_pos - *tail_pos;
if delta[0].abs() <= 1 && delta[1].abs() <= 1 { if delta[0].abs() <= 1 && delta[1].abs() <= 1 {
@@ -123,9 +123,6 @@ fn part_generic<const N: usize>(input: &[u8]) -> Result<String> {
*tail_pos = *tail_pos + step; *tail_pos = *tail_pos + step;
if i == N - 1 {
visited.insert(*tail_pos);
}
ref_pos = *tail_pos; ref_pos = *tail_pos;
} }