make select way faster

This commit is contained in:
jacekpoz 2024-05-09 01:46:12 +02:00
parent 1eedfcbe11
commit 1d3728e795
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
3 changed files with 176 additions and 15 deletions

148
lab3/zad2/Cargo.lock generated
View file

@ -2,6 +2,18 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -33,6 +45,19 @@ version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" 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]] [[package]]
name = "either" name = "either"
version = "1.11.0" version = "1.11.0"
@ -50,6 +75,12 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.153"
@ -75,6 +106,35 @@ dependencies = [
name = "libsort" name = "libsort"
version = "0.1.0" 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]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@ -131,6 +191,27 @@ dependencies = [
"crossbeam-utils", "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]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
@ -138,9 +219,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[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" version = "0.1.0"
dependencies = [ dependencies = [
"dashmap",
"libgen", "libgen",
"libselect", "libselect",
"rayon", "rayon",

View file

@ -8,3 +8,6 @@ libgen = { path = "../../libgen" }
libselect = { path = "../../libselect" } libselect = { path = "../../libselect" }
rayon = "1.10.0" rayon = "1.10.0"
dashmap = "5.5.3" dashmap = "5.5.3"
[profile.dev]
debug = 2

View file

@ -53,6 +53,18 @@ impl NormalSelect {
j j
} }
fn insertion_sort(&mut self, list: &mut Vec<u64>, 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<u64>, lo: usize, hi: usize, ord_stat: usize, k: usize) -> (usize, u64) { fn _select(&mut self, list: &mut Vec<u64>, lo: usize, hi: usize, ord_stat: usize, k: usize) -> (usize, u64) {
if lo == hi { if lo == hi {
return (lo, list[lo]); 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); } if self.should_print { println!("list: {:?}; lo: {lo}; hi: {hi}; ord_stat: {ord_stat}; k: {k}", list); }
let mut medians: Vec<u64> = vec![]; let n = hi - lo + 1;
let mut chunks = list[lo..=hi].chunks(k) let num_groups = if n % 5 == 0 { n / 5 } else { (n / 5) + 1 };
.collect::<Vec<_>>(); let mut medians: Vec<u64> = vec![0; num_groups];
let mut index = 0;
for mut chunk in chunks.iter_mut().map(|c| c.to_vec()) { for i in (lo..=hi).step_by(5) {
self.insertion.sort_mut(&mut chunk); if i + 4 <= hi {
medians.push(chunk[(chunk.len() - 1) / 2]); 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); } if self.should_print { println!("medians: {:?}", medians); }
self.comparisons += self.insertion.num_comp(); let (pivot_index, pivot) = self._select(&mut medians, 0, num_groups - 1, (num_groups + 1) / 2, k);
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);
if self.should_print { if self.should_print {
println!("pivot_index: {pivot_index}; pivot: {pivot}"); println!("pivot_index: {pivot_index}; pivot: {pivot}");
} }