Skip to content

Commit 2f7d19a

Browse files
committed
Use just rand_core and rand_xoshiro.
1 parent 2b83c29 commit 2f7d19a

File tree

4 files changed

+24
-67
lines changed

4 files changed

+24
-67
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Versioning](http://semver.org/spec/v2.0.0.html).
1414
compile, specifically version 1.36.0, so does `im`. This is a breaking change,
1515
but will of course only affect your code if you're using an older `rustc`.
1616

17+
### Fixed
18+
19+
- Fixed a quadratic time worst case scenario in the quicksort implementation for
20+
`Vector`. (#101)
21+
1722
## [13.0.0] - 2019-05-18
1823

1924
The minimum supported Rust version is now 1.34.0.

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ quickcheck = { version = "0.9", optional = true }
3131
proptest = { version = "0.9", optional = true }
3232
serde = { version = "1.0", optional = true }
3333
rayon = { version = "1.0", optional = true }
34-
rand = { version = "0.7", features = ["small_rng"] }
34+
rand_core = "0.5.1"
35+
rand_xoshiro = "0.4.0"
3536

3637
[dev-dependencies]
3738
proptest = "0.9"
3839
serde = "1.0"
3940
serde_json = "1.0"
4041
rayon = "1.0"
42+
rand = { version = "0.7", features = ["small_rng"] }
4143
pretty_assertions = "0.6"
4244
metrohash = "1.0.6"
4345
proptest-derive = "0.1.0"

benches/sort.rs

-60
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,39 @@ use test::Bencher;
88

99
// sorted
1010
#[bench]
11-
<<<<<<< HEAD
1211
fn quicksort_sorted_list_0500(bench: &mut Bencher) {
13-
=======
14-
fn sorted_list_0500(bench: &mut Bencher) {
15-
>>>>>>> Benchmarks for quicksort.
1612
bench.iter(|| {
1713
let mut v1: Vector<_> = (0..500).collect();
1814
v1.sort()
1915
});
2016
}
2117

2218
#[bench]
23-
<<<<<<< HEAD
2419
fn quicksort_sorted_list_1000(bench: &mut Bencher) {
25-
=======
26-
fn sorted_list_1000(bench: &mut Bencher) {
27-
>>>>>>> Benchmarks for quicksort.
2820
bench.iter(|| {
2921
let mut v1: Vector<_> = (0..1000).collect();
3022
v1.sort()
3123
});
3224
}
3325

3426
#[bench]
35-
<<<<<<< HEAD
3627
fn quicksort_sorted_list_1500(bench: &mut Bencher) {
37-
=======
38-
fn sorted_list_1500(bench: &mut Bencher) {
39-
>>>>>>> Benchmarks for quicksort.
4028
bench.iter(|| {
4129
let mut v1: Vector<_> = (0..1500).collect();
4230
v1.sort()
4331
});
4432
}
4533

4634
#[bench]
47-
<<<<<<< HEAD
4835
fn quicksort_sorted_list_2000(bench: &mut Bencher) {
49-
=======
50-
fn sorted_list_2000(bench: &mut Bencher) {
51-
>>>>>>> Benchmarks for quicksort.
5236
bench.iter(|| {
5337
let mut v1: Vector<_> = (0..2000).collect();
5438
v1.sort()
5539
});
5640
}
5741

5842
#[bench]
59-
<<<<<<< HEAD
6043
fn quicksort_sorted_list_2500(bench: &mut Bencher) {
61-
=======
62-
fn sorted_list_2500(bench: &mut Bencher) {
63-
>>>>>>> Benchmarks for quicksort.
6444
bench.iter(|| {
6545
let mut v1: Vector<_> = (0..2500).rev().collect();
6646
v1.sort()
@@ -69,59 +49,39 @@ fn sorted_list_2500(bench: &mut Bencher) {
6949

7050
// reverse sorted
7151
#[bench]
72-
<<<<<<< HEAD
7352
fn quicksort_reverse_sorted_list_0500(bench: &mut Bencher) {
74-
=======
75-
fn reverse_sorted_list_0500(bench: &mut Bencher) {
76-
>>>>>>> Benchmarks for quicksort.
7753
bench.iter(|| {
7854
let mut v1: Vector<_> = (0..500).rev().collect();
7955
v1.sort()
8056
});
8157
}
8258

8359
#[bench]
84-
<<<<<<< HEAD
8560
fn quicksort_reverse_sorted_list_1000(bench: &mut Bencher) {
86-
=======
87-
fn reverse_sorted_list_1000(bench: &mut Bencher) {
88-
>>>>>>> Benchmarks for quicksort.
8961
bench.iter(|| {
9062
let mut v1: Vector<_> = (0..1000).rev().collect();
9163
v1.sort()
9264
});
9365
}
9466

9567
#[bench]
96-
<<<<<<< HEAD
9768
fn quicksort_reverse_sorted_list_1500(bench: &mut Bencher) {
98-
=======
99-
fn reverse_sorted_list_1500(bench: &mut Bencher) {
100-
>>>>>>> Benchmarks for quicksort.
10169
bench.iter(|| {
10270
let mut v1: Vector<_> = (0..1500).rev().collect();
10371
v1.sort()
10472
});
10573
}
10674

10775
#[bench]
108-
<<<<<<< HEAD
10976
fn quicksort_reverse_sorted_list_2000(bench: &mut Bencher) {
110-
=======
111-
fn reverse_sorted_list_2000(bench: &mut Bencher) {
112-
>>>>>>> Benchmarks for quicksort.
11377
bench.iter(|| {
11478
let mut v1: Vector<_> = (0..2000).rev().collect();
11579
v1.sort()
11680
});
11781
}
11882

11983
#[bench]
120-
<<<<<<< HEAD
12184
fn quicksort_reverse_sorted_list_2500(bench: &mut Bencher) {
122-
=======
123-
fn reverse_sorted_list_2500(bench: &mut Bencher) {
124-
>>>>>>> Benchmarks for quicksort.
12585
bench.iter(|| {
12686
let mut v1: Vector<_> = (0..2500).rev().collect();
12787
v1.sort()
@@ -130,11 +90,7 @@ fn reverse_sorted_list_2500(bench: &mut Bencher) {
13090

13191
// shuffled
13292
#[bench]
133-
<<<<<<< HEAD
13493
fn quicksort_shuffled_list_0500(bench: &mut Bencher) {
135-
=======
136-
fn shuffled_list_0500(bench: &mut Bencher) {
137-
>>>>>>> Benchmarks for quicksort.
13894
let mut rng = rand::thread_rng();
13995
bench.iter(|| {
14096
let mut v1: Vec<_> = (0..500).collect();
@@ -145,11 +101,7 @@ fn shuffled_list_0500(bench: &mut Bencher) {
145101
}
146102

147103
#[bench]
148-
<<<<<<< HEAD
149104
fn quicksort_shuffled_list_1000(bench: &mut Bencher) {
150-
=======
151-
fn shuffled_list_1000(bench: &mut Bencher) {
152-
>>>>>>> Benchmarks for quicksort.
153105
let mut rng = rand::thread_rng();
154106
bench.iter(|| {
155107
let mut v1: Vec<_> = (0..1000).collect();
@@ -160,11 +112,7 @@ fn shuffled_list_1000(bench: &mut Bencher) {
160112
}
161113

162114
#[bench]
163-
<<<<<<< HEAD
164115
fn quicksort_shuffled_list_1500(bench: &mut Bencher) {
165-
=======
166-
fn shuffled_list_1500(bench: &mut Bencher) {
167-
>>>>>>> Benchmarks for quicksort.
168116
let mut rng = rand::thread_rng();
169117
bench.iter(|| {
170118
let mut v1: Vec<_> = (0..1500).collect();
@@ -175,11 +123,7 @@ fn shuffled_list_1500(bench: &mut Bencher) {
175123
}
176124

177125
#[bench]
178-
<<<<<<< HEAD
179126
fn quicksort_shuffled_list_2000(bench: &mut Bencher) {
180-
=======
181-
fn shuffled_list_2000(bench: &mut Bencher) {
182-
>>>>>>> Benchmarks for quicksort.
183127
let mut rng = rand::thread_rng();
184128
bench.iter(|| {
185129
let mut v1: Vec<_> = (0..2000).collect();
@@ -190,11 +134,7 @@ fn shuffled_list_2000(bench: &mut Bencher) {
190134
}
191135

192136
#[bench]
193-
<<<<<<< HEAD
194137
fn quicksort_shuffled_list_2500(bench: &mut Bencher) {
195-
=======
196-
fn shuffled_list_2500(bench: &mut Bencher) {
197-
>>>>>>> Benchmarks for quicksort.
198138
let mut rng = rand::thread_rng();
199139
bench.iter(|| {
200140
let mut v1: Vec<_> = (0..2500).collect();

src/sort.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,35 @@
33
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
44

55
use crate::vector::FocusMut;
6+
use rand_core::{RngCore, SeedableRng};
67
use std::cmp::Ordering;
7-
use rand::prelude::*;
8+
9+
fn gen_range<R: RngCore>(rng: &mut R, min: usize, max: usize) -> usize {
10+
let range = max - min;
11+
min + (rng.next_u64() as usize % range)
12+
}
813

914
// Ported from the Java version at:
1015
// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
1116
// Should be O(n) to O(n log n)
12-
pub fn do_quicksort<A, F, R>(vector: &mut FocusMut<A>, left: usize, right: usize, cmp: &F, rng: &mut R)
13-
where
17+
pub fn do_quicksort<A, F, R>(
18+
vector: &mut FocusMut<A>,
19+
left: usize,
20+
right: usize,
21+
cmp: &F,
22+
rng: &mut R,
23+
) where
1424
A: Clone,
1525
F: Fn(&A, &A) -> Ordering,
16-
R: Rng
26+
R: RngCore,
1727
{
1828
if right <= left {
1929
return;
2030
}
2131

2232
let l = left as isize;
2333
let r = right as isize;
24-
let p = rng.gen_range(l, r + 1);
34+
let p = gen_range(rng, left, right + 1) as isize;
2535
let mut l1 = l;
2636
let mut r1 = r;
2737
let mut l2 = l - 1;
@@ -80,7 +90,7 @@ where
8090
A: Clone,
8191
F: Fn(&A, &A) -> Ordering,
8292
{
83-
let mut rng = rand::thread_rng();
93+
let mut rng = rand_xoshiro::Xoshiro256Plus::seed_from_u64(0);
8494
do_quicksort(vector, left, right, cmp, &mut rng);
8595
}
8696

0 commit comments

Comments
 (0)