From 1d3728e795103d553fb0d403490c8aa16e0d5444 Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Thu, 9 May 2024 01:46:12 +0200 Subject: [PATCH] make select way faster --- lab3/zad2/Cargo.lock | 148 ++++++++++++++++++++++++++++++++- lab3/zad2/Cargo.toml | 3 + libselect/src/normal_select.rs | 40 +++++---- 3 files changed, 176 insertions(+), 15 deletions(-) diff --git a/lab3/zad2/Cargo.lock b/lab3/zad2/Cargo.lock index 67bf7b2..286e2c5 100644 --- a/lab3/zad2/Cargo.lock +++ b/lab3/zad2/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "cfg-if" version = "1.0.0" @@ -33,6 +45,19 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "either" version = "1.11.0" @@ -50,6 +75,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "libc" version = "0.2.153" @@ -75,6 +106,35 @@ dependencies = [ name = "libsort" version = "0.1.0" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -131,6 +191,27 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -138,9 +219,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "zad4" +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "zad2" version = "0.1.0" dependencies = [ + "dashmap", "libgen", "libselect", "rayon", diff --git a/lab3/zad2/Cargo.toml b/lab3/zad2/Cargo.toml index 4971c79..50f3b5a 100644 --- a/lab3/zad2/Cargo.toml +++ b/lab3/zad2/Cargo.toml @@ -8,3 +8,6 @@ libgen = { path = "../../libgen" } libselect = { path = "../../libselect" } rayon = "1.10.0" dashmap = "5.5.3" + +[profile.dev] +debug = 2 diff --git a/libselect/src/normal_select.rs b/libselect/src/normal_select.rs index 51025c0..b84e55d 100644 --- a/libselect/src/normal_select.rs +++ b/libselect/src/normal_select.rs @@ -53,6 +53,18 @@ impl NormalSelect { j } + fn insertion_sort(&mut self, list: &mut Vec, lo: usize, hi: usize) { + for i in (lo + 1)..=hi { + let mut j = i as usize; + + use CompareResult::*; + while j > 0 && self.compare(list[j - 1], list[j]) == GREATER { + self.swap(list, j - 1, j); + j -= 1; + } + } + } + fn _select(&mut self, list: &mut Vec, lo: usize, hi: usize, ord_stat: usize, k: usize) -> (usize, u64) { if lo == hi { return (lo, list[lo]); @@ -60,24 +72,24 @@ impl NormalSelect { if self.should_print { println!("list: {:?}; lo: {lo}; hi: {hi}; ord_stat: {ord_stat}; k: {k}", list); } - let mut medians: Vec = vec![]; - let mut chunks = list[lo..=hi].chunks(k) - .collect::>(); - - for mut chunk in chunks.iter_mut().map(|c| c.to_vec()) { - self.insertion.sort_mut(&mut chunk); - medians.push(chunk[(chunk.len() - 1) / 2]); + let n = hi - lo + 1; + let num_groups = if n % 5 == 0 { n / 5 } else { (n / 5) + 1 }; + let mut medians: Vec = vec![0; num_groups]; + let mut index = 0; + for i in (lo..=hi).step_by(5) { + if i + 4 <= hi { + self.insertion_sort(list, i, i + 4); + medians[index] = list[i + 2]; + index += 1; + } else { + self.insertion_sort(list, i, hi); + medians[index] = list[i + ((hi - i) / 2)]; + } } if self.should_print { println!("medians: {:?}", medians); } - self.comparisons += self.insertion.num_comp(); - self.swaps += self.insertion.num_swap(); - self.insertion.reset_state(); - - let n = hi - lo; - - let (pivot_index, pivot) = self._select(&mut medians, 0, n.div_ceil(k) - 1, (n.div_ceil(k) - 1).div_ceil(2), k); + let (pivot_index, pivot) = self._select(&mut medians, 0, num_groups - 1, (num_groups + 1) / 2, k); if self.should_print { println!("pivot_index: {pivot_index}; pivot: {pivot}"); }