feat: lots of optimization in parse, cargo bench

thecoded.prof 6357a178 1a39daec

verified
Changed files
+91 -8
2025
+23
2025/Cargo.lock
··· 13 13 version = "0.1.0" 14 14 dependencies = [ 15 15 "anyhow", 16 + "atoi_simd", 17 + "memchr", 16 18 ] 19 + 20 + [[package]] 21 + name = "atoi_simd" 22 + version = "0.17.0" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "8ad17c7c205c2c28b527b9845eeb91cf1b4d008b438f98ce0e628227a822758e" 25 + dependencies = [ 26 + "debug_unsafe", 27 + ] 28 + 29 + [[package]] 30 + name = "debug_unsafe" 31 + version = "0.1.3" 32 + source = "registry+https://github.com/rust-lang/crates.io-index" 33 + checksum = "85d3cef41d236720ed453e102153a53e4cc3d2fde848c0078a50cf249e8e3e5b" 34 + 35 + [[package]] 36 + name = "memchr" 37 + version = "2.7.6" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
+2
2025/Cargo.toml
··· 5 5 6 6 [dependencies] 7 7 anyhow = "1.0.100" 8 + atoi_simd = "0.17.0" 9 + memchr = "2.7.6"
+48 -6
2025/src/days/one/secret_entrance.rs
··· 1 + use atoi_simd::parse as parse_i32; 2 + 1 3 pub fn main() -> anyhow::Result<()> { 2 4 crate::run("Secret Entrance", "inputs/day1.txt", parse, part_a, part_b) 3 5 } 4 6 5 - fn parse(input: &str) -> Vec<i32> { 6 - input 7 - .lines() 8 - .filter(|line| !line.is_empty()) 9 - .filter_map(|line| line.replace("L", "-").replace("R", "").parse().ok()) 10 - .collect() 7 + fn parse(input: &[u8]) -> Vec<i32> { 8 + let mut out = Vec::with_capacity(4503); 9 + let mut start = 0; 10 + 11 + while start < input.len() { 12 + let end = match memchr::memchr(b'\n', &input[start..]) { 13 + Some(index) => start + index, 14 + None => input.len(), 15 + }; 16 + let line = &input[start..end]; 17 + 18 + if !line.is_empty() { 19 + let mut buf = [0u8; 4]; 20 + let mut len = 0usize; 21 + let mut seen_digit = false; 22 + 23 + for &b in line { 24 + match b { 25 + b'L' => { 26 + if len == 0 { 27 + buf[len] = b'-'; 28 + len += 1; 29 + } 30 + } 31 + b'0'..=b'9' => { 32 + seen_digit = true; 33 + buf[len] = b; 34 + len += 1; 35 + } 36 + _ => { 37 + len = 0; 38 + break; 39 + } 40 + } 41 + } 42 + if seen_digit && len > 0 { 43 + if let Ok(num) = parse_i32(&buf[..len]) { 44 + out.push(num); 45 + } 46 + } 47 + } 48 + 49 + start = end + 1; 50 + } 51 + 52 + out 11 53 } 12 54 13 55 fn part_a(input: Vec<i32>) -> usize {
+4 -2
2025/src/lib.rs
··· 13 13 ) -> Result<()> 14 14 where 15 15 T: Clone, 16 - P: Fn(&str) -> T, 16 + P: Fn(&[u8]) -> T, 17 17 A: Fn(T) -> RA, 18 18 B: Fn(T) -> RB, 19 19 RA: Display, 20 20 RB: Display, 21 21 { 22 + let file = &fs::read_to_string(input_path)?; 23 + let bytes = file.as_bytes(); 22 24 let label_parse = format!("{name} Parse"); 23 25 let parse_start = Instant::now(); 24 - let input = parse(&fs::read_to_string(input_path)?); 26 + let input = parse(bytes); 25 27 let parse_elapsed = parse_start.elapsed(); 26 28 println!("{label_parse}"); 27 29 println!("{}", "-".repeat(label_parse.len()));
+14
2025/src/main.rs
··· 1 + #![feature(test)] 2 + extern crate test; 3 + 1 4 fn main() -> anyhow::Result<()> { 2 5 aoc2025::days::one::secret_entrance::main()?; 3 6 Ok(()) 4 7 } 8 + 9 + #[cfg(test)] 10 + mod tests { 11 + use aoc2025::days; 12 + use test::Bencher; 13 + 14 + #[bench] 15 + fn day1(b: &mut Bencher) { 16 + b.iter(|| days::one::secret_entrance::main()) 17 + } 18 + }