Skip to content

Commit

Permalink
2023-05: ~8.9x speedup through parallelization
Browse files Browse the repository at this point in the history
Needed to split up the time ranges into batches for this to work. Will
take up 100% of CPU for >25s on a pretty good rig.

Still not optimized enough, but not unexpected for such a naive
implementation.
  • Loading branch information
MLNW committed Dec 5, 2023
1 parent bb5ba20 commit cfad77a
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 17 deletions.
81 changes: 81 additions & 0 deletions 2023-rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions 2023-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ test_lib = []
[dependencies]
itertools = "0.12.0"
pico-args = "0.5.0"
rayon = "1.8.0"
regex = "1.10.2"
12 changes: 6 additions & 6 deletions 2023-rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.

| Day | Part 1 | Part 2 |
| :---: | :---: | :---: |
| [Day 1](./src/bin/01.rs) | `64.7µs` | `659.1µs` |
| [Day 2](./src/bin/02.rs) | `41.4µs` | `48.5µs` |
| [Day 3](./src/bin/03.rs) | `467.4µs` | `428.0µs` |
| [Day 4](./src/bin/04.rs) | `95.3µs` | `19.7ms` |
| [Day 5](./src/bin/05.rs) | `31.2µs` | `236.6s` |
| [Day 1](./src/bin/01.rs) | `63.6µs` | `634.3µs` |
| [Day 2](./src/bin/02.rs) | `41.3µs` | `47.2µs` |
| [Day 3](./src/bin/03.rs) | `429.8µs` | `421.7µs` |
| [Day 4](./src/bin/04.rs) | `97.3µs` | `19.2ms` |
| [Day 5](./src/bin/05.rs) | `30.3µs` | `26.5s` |

**Total: 236.62s**
**Total: 26520.97ms**
<!--- benchmarking table --->

## Usage
Expand Down
44 changes: 33 additions & 11 deletions 2023-rust/src/bin/05.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::collections::{HashMap, VecDeque};
use std::{
collections::{HashMap, VecDeque},
time::SystemTime,
};

use itertools::Itertools;
use rayon::iter::{IntoParallelIterator, ParallelIterator};

advent_of_code::solution!(5);

Expand Down Expand Up @@ -48,20 +52,38 @@ fn solve_part_one(seeds: Vec<u64>, maps: &Vec<HashMap<RangeKey, MapEntry>>) -> O
pub fn part_two(input: &str) -> Option<u64> {
let (seeds, maps) = parse_input(input);

let mut min: u64 = std::u64::MAX;
let max_seed_range_length = 10_000_000;
let mut seed_ranges: Vec<(u64, u64)> = Vec::new();
for mut chunk in &seeds.iter().chunks(2) {
let start = chunk.next().unwrap();
let length = chunk.next().unwrap();
let current_seeds = (*start..*start + *length).collect_vec();

let current_min = solve_part_one(current_seeds, &maps).unwrap();
println!("{start}-{length}, current min: {current_min}, last min: {min}");
if current_min < min {
min = current_min;
let mut start = *chunk.next().unwrap();
let length = *chunk.next().unwrap();
let stop = start + length;

loop {
if start + max_seed_range_length < stop {
seed_ranges.push((start, start + max_seed_range_length));
start += max_seed_range_length;
} else {
seed_ranges.push((start, stop));
break;
}
}
}

Some(min)
seed_ranges
.into_par_iter()
.filter_map(|(start, stop)| {
let timer = SystemTime::now();
let current_seeds = (start..stop).collect_vec();
let result = solve_part_one(current_seeds, &maps);
println!(
"[{start}-{stop}] in {:?} => {:?}",
timer.elapsed().unwrap(),
result
);
result
})
.min()
}

fn find_map_entry(map: &HashMap<RangeKey, MapEntry>, value: u64) -> Option<MapEntry> {
Expand Down

0 comments on commit cfad77a

Please sign in to comment.