Optimize year2020/day01 by sorting the input for average-case speedup#86
Merged
Conversation
maneatingape
requested changes
Jun 17, 2026
maneatingape
left a comment
Owner
There was a problem hiding this comment.
Nice observation!
Before:
test year2020::day01::parse_bench ... bench: 576.99 ns/iter (+/- 47.59)
test year2020::day01::part1_bench ... bench: 227.95 ns/iter (+/- 4.93)
test year2020::day01::part2_bench ... bench: 9,203.40 ns/iter (+/- 1,601.62)
After:
test year2020::day01::parse_bench ... bench: 1,291.23 ns/iter (+/- 31.08)
test year2020::day01::part1_bench ... bench: 160.66 ns/iter (+/- 48.27)
test year2020::day01::part2_bench ... bench: 416.53 ns/iter (+/- 2.57)
Could this be counted as a valid heuristic?
Absolutely! This feels similar to the pivot selection of quicksort, not theoretically guaranteed to avoid the worst case O complexity, but faster in practice.
|
|
||
| pub fn parse(input: &str) -> Vec<usize> { | ||
| input.iter_unsigned().collect() | ||
| let mut numbers: Vec<usize> = input.iter_unsigned().collect(); |
Owner
There was a problem hiding this comment.
Code looks good.
Minor suggestion: Would you mind adding a small comment, explaining this to the reader, i.e something like: It's not necessary for correctness but improves the average running time for most (all?) inputs.
Contributor
Author
There was a problem hiding this comment.
I've added the comment and squashed the commits. Let me know if this looks good.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
I don't know if this counts as a performance improvement because it does not improve the algorithm per se. I think it is akin to assuming that the solutions always follow a normal distribution, i.e., after sorting, the solutions end up closer to the middle of the vector instead of the extremes. I have only tested this with three different inputs, and they all seem well-behaved. The numbers from the second input are the most interesting.
INPUT 1
From:
To:
Total save: ~853 ns (similar numbers for the third input). The increase in parsing is because the sorting is done there.
INPUT 2
From:
To:
Total save: ~4,777.52ns.
Could this be counted as a valid heuristic? I just found the behavior interesting, but no worries if you decide to skip it.
Type of change
Checklist
using the same naming conventions. Code should be portable, avoiding any
architecture-specific intrinsics.
cargo testcargo fmt -- `find . -name "*.rs"`cargo clippy --all-targets --all-features