[TWEAK] Performance improvement by dropping the need for a hashmap and using the stack indices directly
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -7,6 +7,7 @@ name = "advent-of-code-2022-rust"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"nohash-hasher",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
@@ -32,6 +33,12 @@ version = "2.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nohash-hasher"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1"
|
regex = "1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
|
nohash-hasher = "0.2.0"
|
||||||
24
src/day5.rs
24
src/day5.rs
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use nohash_hasher::{BuildNoHashHasher, NoHashHasher};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use crate::day_solver::DaySolver;
|
use crate::day_solver::DaySolver;
|
||||||
|
|
||||||
@@ -25,15 +27,14 @@ impl StackInstruction {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Day5 {
|
pub struct Day5 {
|
||||||
stacks: Vec<Vec<char>>,
|
stacks: Vec<Vec<char>>,
|
||||||
stack_ids_rev: FxHashMap<u8, usize>,
|
|
||||||
instructions: Vec<StackInstruction>
|
instructions: Vec<StackInstruction>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Day5 {
|
impl Day5 {
|
||||||
fn execute_instruction_part1(&mut self, instr: &StackInstruction) {
|
fn execute_instruction_part1(&mut self, instr: &StackInstruction) {
|
||||||
for _ in 0..instr.amount {
|
for _ in 0..instr.amount {
|
||||||
let moving_crate = self.stacks[self.stack_ids_rev[&instr.from]].pop().unwrap();
|
let moving_crate = self.stacks[instr.from as usize].pop().unwrap();
|
||||||
self.stacks[self.stack_ids_rev[&instr.to]].push(moving_crate);
|
self.stacks[instr.to as usize].push(moving_crate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +49,12 @@ impl Day5 {
|
|||||||
|
|
||||||
fn execute_instruction_part2(&mut self, instr: &StackInstruction) {
|
fn execute_instruction_part2(&mut self, instr: &StackInstruction) {
|
||||||
|
|
||||||
let from_stack = &self.stacks[self.stack_ids_rev[&instr.from]];
|
// TODO prevent copying into a Vec here (we don't need a stack allocation...)
|
||||||
|
let from_stack = &self.stacks[instr.from as usize];
|
||||||
let from_stack_remaining = from_stack.len() - instr.amount as usize;
|
let from_stack_remaining = from_stack.len() - instr.amount as usize;
|
||||||
let to_move: Vec<char> = from_stack.iter().skip(from_stack_remaining).cloned().collect();
|
let to_move: Vec<char> = from_stack.iter().skip(from_stack_remaining).cloned().collect();
|
||||||
self.stacks[self.stack_ids_rev[&instr.to]].extend(to_move);
|
self.stacks[instr.to as usize].extend(to_move);
|
||||||
self.stacks[self.stack_ids_rev[&instr.from]].truncate(from_stack_remaining);
|
self.stacks[instr.from as usize].truncate(from_stack_remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_instructions_part2(&self) -> Day5 {
|
fn execute_instructions_part2(&self) -> Day5 {
|
||||||
@@ -87,15 +89,19 @@ impl Day5 {
|
|||||||
}
|
}
|
||||||
let stack_ids: Vec<u8> = stack_id_strs.iter().map(|s| s.parse::<u8>().unwrap()).collect();
|
let stack_ids: Vec<u8> = stack_id_strs.iter().map(|s| s.parse::<u8>().unwrap()).collect();
|
||||||
|
|
||||||
let mut stacks: Vec<Vec<char>> = vec![Vec::with_capacity(stack_lines.len() - 1); stack_id_idxs.len()];
|
let mut stacks: Vec<Vec<char>> = vec![Vec::with_capacity(stack_lines.len() - 1);
|
||||||
|
stack_ids.iter().max().unwrap().to_owned() as usize + 1];
|
||||||
for stack_line in stack_lines.iter().rev().skip(1) {
|
for stack_line in stack_lines.iter().rev().skip(1) {
|
||||||
stack_id_idxs.iter().enumerate()
|
stack_id_idxs.iter().enumerate()
|
||||||
.for_each(|(i, stack_id_idx)| if let Some(c) = stack_line.chars().nth(stack_id_idx.to_owned()).filter(|c| !c.is_whitespace()) { stacks[i].push(c) })
|
.for_each(|(i, stack_id_idx)| if let Some(c) = stack_line.chars()
|
||||||
|
.nth(stack_id_idx.to_owned())
|
||||||
|
.filter(|c| !c.is_whitespace()) {
|
||||||
|
stacks[stack_ids[i] as usize].push(c)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return Day5 {
|
return Day5 {
|
||||||
stacks,
|
stacks,
|
||||||
stack_ids_rev: FxHashMap::from_iter(stack_ids.iter().enumerate().map(|(k, v)| (v.clone(), k))),
|
|
||||||
instructions: instruction_lines.iter().map(|s| StackInstruction::parse(s)).collect()
|
instructions: instruction_lines.iter().map(|s| StackInstruction::parse(s)).collect()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user