From 749255817f35645638a3597f9195c9f49fa1d6ab Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 10:26:15 +0200 Subject: [PATCH 1/8] fix: Jean bonisseur de la Bath --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8e9c5be..a3886d4 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,6 @@ cargo codspeed run -m walltime ``` Note: You can also set the `CODSPEED_RUNNER_MODE` environment variable to `walltime` to avoid passing `-m walltime` every time. + +from +jean bonisseur de la bath \ No newline at end of file From 0f7bd0515abd78c8388d1508c53b85195f774245 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 10:27:33 +0200 Subject: [PATCH 2/8] push --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a3886d4..496d8ee 100644 --- a/README.md +++ b/README.md @@ -35,5 +35,5 @@ cargo codspeed run -m walltime Note: You can also set the `CODSPEED_RUNNER_MODE` environment variable to `walltime` to avoid passing `-m walltime` every time. -from -jean bonisseur de la bath \ No newline at end of file + + From f24dbc125a00740f78b7ed0f646d8ff79ad0a6fd Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 10:56:38 +0200 Subject: [PATCH 3/8] fix: using deque --- src/bfs.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bfs.rs b/src/bfs.rs index 487fddc..d31a1ff 100644 --- a/src/bfs.rs +++ b/src/bfs.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashSet, VecDeque}; /// A simple graph represented as an adjacency list #[derive(Debug, Clone)] @@ -25,23 +25,23 @@ impl Graph { /// Naive BFS implementation using Vec as a queue (intentionally slow) /// Returns the order in which nodes were visited -pub fn bfs_naive(graph: &Graph, start: usize) -> Vec { +pub fn bfs_naive(graph: &Graph, start: usize) -> VecDeque { let mut visited = HashSet::new(); - let mut queue = Vec::new(); // Using Vec instead of VecDeque - intentionally inefficient! - let mut result = Vec::new(); + let mut queue = VecDeque::new(); // Using Vec instead of VecDeque - intentionally inefficient! + let mut result = VecDeque::new(); - queue.push(start); + queue.push_back(start); visited.insert(start); while !queue.is_empty() { // remove(0) is O(n) - this makes BFS slow! - let node = queue.remove(0); - result.push(node); + let node = queue.pop_front().unwrap(); + result.push_back(node); if let Some(neighbors) = graph.adjacency.get(node) { for &neighbor in neighbors { if visited.insert(neighbor) { - queue.push(neighbor); + queue.push_back(neighbor); } } } From fd33a4435e35f5c38c8e1d433af79136ab5f9e27 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 11:10:24 +0200 Subject: [PATCH 4/8] moving element --- src/bfs.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/bfs.rs b/src/bfs.rs index d31a1ff..8684191 100644 --- a/src/bfs.rs +++ b/src/bfs.rs @@ -27,15 +27,13 @@ impl Graph { /// Returns the order in which nodes were visited pub fn bfs_naive(graph: &Graph, start: usize) -> VecDeque { let mut visited = HashSet::new(); - let mut queue = VecDeque::new(); // Using Vec instead of VecDeque - intentionally inefficient! - let mut result = VecDeque::new(); + let mut queue = VecDeque::with_capacity(256); // Using Vec instead of VecDeque - intentionally inefficient! + let mut result = VecDeque::with_capacity(256); queue.push_back(start); visited.insert(start); - while !queue.is_empty() { - // remove(0) is O(n) - this makes BFS slow! - let node = queue.pop_front().unwrap(); + while let Some(node) = queue.pop_front() { result.push_back(node); if let Some(neighbors) = graph.adjacency.get(node) { From 2f4b2c419b67319cdc2bfe3f238d1359da6fd072 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 11:15:43 +0200 Subject: [PATCH 5/8] removing the hashset --- src/bfs.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bfs.rs b/src/bfs.rs index 8684191..b0f1d6d 100644 --- a/src/bfs.rs +++ b/src/bfs.rs @@ -26,19 +26,20 @@ impl Graph { /// Naive BFS implementation using Vec as a queue (intentionally slow) /// Returns the order in which nodes were visited pub fn bfs_naive(graph: &Graph, start: usize) -> VecDeque { - let mut visited = HashSet::new(); - let mut queue = VecDeque::with_capacity(256); // Using Vec instead of VecDeque - intentionally inefficient! + let mut visited = [false; 10000]; + let mut queue = VecDeque::with_capacity(256); let mut result = VecDeque::with_capacity(256); queue.push_back(start); - visited.insert(start); + visited[start] = true; while let Some(node) = queue.pop_front() { result.push_back(node); if let Some(neighbors) = graph.adjacency.get(node) { for &neighbor in neighbors { - if visited.insert(neighbor) { + if !visited[neighbor] { + visited[neighbor] = true; queue.push_back(neighbor); } } From d2fb616552551b65645ee9c683a380247c498225 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 12:12:55 +0200 Subject: [PATCH 6/8] testing contrast --- src/lut_filters.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lut_filters.rs b/src/lut_filters.rs index a73068c..6b6ba37 100644 --- a/src/lut_filters.rs +++ b/src/lut_filters.rs @@ -42,24 +42,28 @@ mod naive { pub fn apply_brightness_contrast(img: &RgbImage, brightness: i16, contrast: f32) -> RgbImage { let (width, height) = img.dimensions(); let mut output = ImageBuffer::new(width, height); + let mut c_table: [u8; 256] = [0; 256]; + + + for i in 0..256 { + let f = i as f32; + c_table[i] = (((f - 128.0) * (1.0 + contrast)) + 128.0 + (brightness as f32)).clamp(0.0, 255.0) as u8; + } + + for (x, y, pixel) in img.enumerate_pixels() { let r = pixel[0] as f32; let g = pixel[1] as f32; let b = pixel[2] as f32; - // Apply contrast and brightness (5 FP ops per channel!) - let r = ((r - 128.0) * (1.0 + contrast)) + 128.0 + brightness as f32; - let g = ((g - 128.0) * (1.0 + contrast)) + 128.0 + brightness as f32; - let b = ((b - 128.0) * (1.0 + contrast)) + 128.0 + brightness as f32; - output.put_pixel( x, y, Rgb([ - r.clamp(0.0, 255.0) as u8, - g.clamp(0.0, 255.0) as u8, - b.clamp(0.0, 255.0) as u8, + c_table[r as usize], + c_table[g as usize], + c_table[b as usize], ]), ); } From 06fe4fd0a7b9c4dadaf0ae56d30a216194fd8cc3 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 12:20:52 +0200 Subject: [PATCH 7/8] gamma --- src/lut_filters.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lut_filters.rs b/src/lut_filters.rs index 6b6ba37..250f1f2 100644 --- a/src/lut_filters.rs +++ b/src/lut_filters.rs @@ -77,11 +77,16 @@ mod naive { let (width, height) = img.dimensions(); let mut output = ImageBuffer::new(width, height); + let mut gamma_table = [0u8; 256]; + for i in 0..250 { + gamma_table[i] = ((i as f32 / 255.0).powf(1.0 / gamma) * 255.0) as u8; + } + for (x, y, pixel) in img.enumerate_pixels() { // powf() is VERY expensive - this is why we need a LUT! - let r = (pixel[0] as f32 / 255.0).powf(1.0 / gamma) * 255.0; - let g = (pixel[1] as f32 / 255.0).powf(1.0 / gamma) * 255.0; - let b = (pixel[2] as f32 / 255.0).powf(1.0 / gamma) * 255.0; + let r = gamma_table[pixel[0] as usize]; + let g = gamma_table[pixel[1] as usize]; + let b = gamma_table[pixel[2] as usize]; output.put_pixel(x, y, Rgb([r as u8, g as u8, b as u8])); } From 8c952b65848cf772cbcbcf794833ab5d987ec314 Mon Sep 17 00:00:00 2001 From: Frederic Taillandier Date: Wed, 8 Oct 2025 15:04:14 +0200 Subject: [PATCH 8/8] test --- Cargo.lock | 1 + Cargo.toml | 1 + src/dna_matcher.rs | 6 ++++-- src/lut_filters.rs | 5 +++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c337c95..50664d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -425,6 +425,7 @@ dependencies = [ "image", "image-compare", "rand", + "rayon", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f4172be..f4ccf6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ path = "src/lib.rs" rand = "0.8" image = "0.25" image-compare = "0.5.0" +rayon = "1.11.0" [dev-dependencies] divan = { version = "4.0.2", package = "codspeed-divan-compat" } diff --git a/src/dna_matcher.rs b/src/dna_matcher.rs index d99c90e..b9325d7 100644 --- a/src/dna_matcher.rs +++ b/src/dna_matcher.rs @@ -1,9 +1,11 @@ +use rayon::prelude::*; + /// Naive approach: Read the entire file as a string and filter lines pub fn naive_dna_matcher(genome: &str, pattern: &str) -> Vec { genome - .lines() + .par_lines() // Use parallel lines iterator .filter(|line| !line.starts_with('>')) // Skip headers - .filter(|line| line.contains(pattern)) + .filter(|line| line.contains(pattern)) .map(|s| s.to_string()) .collect() } diff --git a/src/lut_filters.rs b/src/lut_filters.rs index 250f1f2..df4d1e1 100644 --- a/src/lut_filters.rs +++ b/src/lut_filters.rs @@ -78,12 +78,13 @@ mod naive { let mut output = ImageBuffer::new(width, height); let mut gamma_table = [0u8; 256]; + let pow_gamma = 1.0 / gamma; + for i in 0..250 { - gamma_table[i] = ((i as f32 / 255.0).powf(1.0 / gamma) * 255.0) as u8; + gamma_table[i] = ((i as f32 / 255.0).powf(pow_gamma) * 255.0) as u8; } for (x, y, pixel) in img.enumerate_pixels() { - // powf() is VERY expensive - this is why we need a LUT! let r = gamma_table[pixel[0] as usize]; let g = gamma_table[pixel[1] as usize]; let b = gamma_table[pixel[2] as usize];