From b7d6d4039476625ee9c2aebf640836dd73632d74 Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 17 Dec 2020 16:22:26 +0100 Subject: [PATCH] Optimize 2020/17 further This avoids some hashing per step and unneeded copies. About 10% faster. --- 2020/src/bin/day17.rs | 11 ++++++----- 2020/src/grid.rs | 6 +++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/2020/src/bin/day17.rs b/2020/src/bin/day17.rs index 4d15c2f..fd12c1e 100644 --- a/2020/src/bin/day17.rs +++ b/2020/src/bin/day17.rs @@ -12,11 +12,12 @@ fn parse_input P + Copy>(raw: &str, mut raw.lines() .enumerate() .flat_map(move |(y, l)| l.bytes().enumerate().map(move |(x, b)| (pos_gen((x, y)), b.into()))) + .filter(|(_, c)| c == &Cell::Alive) .collect() } fn count_live_neighbors(p: &P, grid: &Grid) -> usize { - p.neighbors().iter().filter(|&n| grid.get(*n) == Cell::Alive).count() + p.neighbors().iter().filter(|&n| grid.get(n) == Cell::Alive).count() } fn make_step(input: Grid) -> Grid { @@ -24,10 +25,9 @@ fn make_step(input: Grid) -> Grid { input .fields .keys() - .filter(|&&p| readonly.get(p) == Cell::Alive) .flat_map(|p| p.neighbors()) .map(|pos| { - let cell = readonly.get(pos); + let cell = readonly.get(&pos); let new = match (&cell, count_live_neighbors(&pos, &readonly)) { (Cell::Alive, 2..=3) => Cell::Alive, (Cell::Dead, 3) => Cell::Alive, @@ -35,6 +35,7 @@ fn make_step(input: Grid) -> Grid { }; (pos, new) }) + .filter(|(_, c)| c == &Cell::Alive) .collect() } @@ -79,14 +80,14 @@ mod tests { #[bench] fn bench_3d_parse(b: &mut test::Bencher) { let raw = read_input(); - b.iter(|| assert_eq!(parse_input(black_box(&raw), |(x, y)| Position3D::from((x, y, 0))).fields.len(), 64)); + b.iter(|| assert_eq!(parse_input(black_box(&raw), |(x, y)| Position3D::from((x, y, 0))).fields.len(), 43)); } #[bench] #[rustfmt::skip] fn bench_4d_parse(b: &mut test::Bencher) { let raw = read_input(); - b.iter(|| assert_eq!(parse_input(black_box(&raw), |(x, y)| Position4D::from((x, y, 0, 0))).fields.len(), 64)); + b.iter(|| assert_eq!(parse_input(black_box(&raw), |(x, y)| Position4D::from((x, y, 0, 0))).fields.len(), 43)); } #[bench] diff --git a/2020/src/grid.rs b/2020/src/grid.rs index fadac61..a287722 100644 --- a/2020/src/grid.rs +++ b/2020/src/grid.rs @@ -13,10 +13,14 @@ pub struct Grid { } impl Grid { - pub fn get>(&self, pos: Pos) -> T { + pub fn get_convert>(&self, pos: Pos) -> T { self.fields.get(&pos.into()).copied().unwrap_or_else(|| T::default()) } + pub fn get(&self, pos: &P) -> T { + self.fields.get(pos).copied().unwrap_or_else(|| T::default()) + } + pub fn insert>(&mut self, pos: Pos, t: T) { self.fields.insert(pos.into(), t); }