From cec83937709db98117c094455f448a2c355ae8e4 Mon Sep 17 00:00:00 2001 From: Xymist Date: Fri, 26 Aug 2022 16:29:11 +0100 Subject: [PATCH] Remove multithreading for sorting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The relevant processes are so fast, mutexes and mutex locks are so expensive, and iterators so efficient, that it's actually faster to run single-threaded across all the data than to spin up a bunch of threads and have them basically spinlock waiting for the global mutex involved either directly or in a channel. ivy_files(kubernetes) time: [10.209 ms 10.245 ms 10.286 ms] change: [-36.781% -36.178% -35.601%] (p = 0.00 < 0.05) Performance has improved. ivy_match(file.lua) time: [1.1626 µs 1.1668 µs 1.1709 µs] change: [+0.2131% +1.5409% +2.9109%] (p = 0.02 < 0.05) Change within noise threshold. --- examples/filename_search.rs | 4 +++- rust/lib.rs | 2 +- rust/matcher.rs | 4 ++-- rust/sorter.rs | 36 ++++++++---------------------------- 4 files changed, 14 insertions(+), 32 deletions(-) diff --git a/examples/filename_search.rs b/examples/filename_search.rs index 0e91b96..68cba68 100644 --- a/examples/filename_search.rs +++ b/examples/filename_search.rs @@ -1,5 +1,7 @@ use ivyrs::inner_files; pub fn main() { - inner_files("file.go".to_owned(), "/tmp/ivy-trees/kubernetes".to_owned()); + let res = inner_files("file.go".to_owned(), "/tmp/ivy-trees/kubernetes".to_owned()); + + println!("{}", res); } diff --git a/rust/lib.rs b/rust/lib.rs index b1e6cf0..74bda52 100644 --- a/rust/lib.rs +++ b/rust/lib.rs @@ -52,7 +52,7 @@ pub extern "C" fn ivy_match(c_pattern: *const c_char, c_text: *const c_char) -> pub fn inner_match(pattern: String, text: String) -> i32 { let m = matcher::Matcher::new(pattern); - m.score(text) as i32 + m.score(text.as_str()) as i32 } #[no_mangle] diff --git a/rust/matcher.rs b/rust/matcher.rs index 0560717..cbbf6d7 100644 --- a/rust/matcher.rs +++ b/rust/matcher.rs @@ -15,9 +15,9 @@ impl Matcher { } } - pub fn score(&self, text: String) -> i64 { + pub fn score(&self, text: &str) -> i64 { self.matcher - .fuzzy_indices(&text, &self.pattern) + .fuzzy_indices(text, &self.pattern) .map(|(score, _indices)| score) .unwrap_or_default() } diff --git a/rust/sorter.rs b/rust/sorter.rs index 83ba5b9..cc7c31b 100644 --- a/rust/sorter.rs +++ b/rust/sorter.rs @@ -24,36 +24,16 @@ impl Options { } pub fn sort_strings(options: Options, strings: Vec) -> Vec { - let mut matches = Vec::new(); - let matcher = Arc::new(matcher::Matcher::new(options.pattern)); + let matcher = matcher::Matcher::new(options.pattern); - let pool = thread_pool::ThreadPool::new(std::thread::available_parallelism().unwrap().get()); - - let (tx, rx) = mpsc::channel::(); - - for string in strings { - let thread_matcher = Arc::clone(&matcher); - let thread_transmitter = tx.clone(); - pool.execute(move || { - let score = thread_matcher.score(string.to_string()); - if score > 25 { - thread_transmitter - .send(Match { - score, - content: string, - }) - .expect("Failed to push data to channel"); - } + let mut matches = strings + .into_iter() + .map(|candidate| Match { + score: matcher.score(candidate.as_str()), + content: candidate, }) - } - - drop(pool); - drop(tx); - - while let Ok(result) = rx.recv() { - matches.push(result) - } - + .filter(|m| m.score > 25) + .collect::>(); matches.sort_by(|a, b| a.score.cmp(&b.score)); matches }