Skip to content

Commit 61691c2

Browse files
committed
std: Make merge_sort faster
1 parent 9e4962a commit 61691c2

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

src/libstd/sort.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Module: sort
33
44
Sorting methods
55
*/
6-
import vec::{len, slice};
6+
import vec::len;
77

88
export merge_sort;
99
export quick_sort;
@@ -21,29 +21,41 @@ Has worst case O(n log n) performance, best case O(n), but
2121
is not space efficient. This is a stable sort.
2222
*/
2323
fn merge_sort<T: copy>(le: le<T>, v: [const T]) -> [T] {
24+
type slice = (uint, uint);
25+
26+
ret merge_sort_(le, v, (0u, len(v)));
27+
28+
fn merge_sort_<T: copy>(le: le<T>, v: [const T], slice: slice) -> [T] {
29+
let begin = tuple::first(slice);
30+
let end = tuple::second(slice);
31+
32+
let v_len = end - begin;
33+
if v_len == 0u { ret []; }
34+
if v_len == 1u { ret [v[begin]]; }
35+
36+
let mid = v_len / 2u + begin;
37+
let a = (begin, mid);
38+
let b = (mid, end);
39+
ret merge(le, merge_sort_(le, v, a), merge_sort_(le, v, b));
40+
}
41+
2442
fn merge<T: copy>(le: le<T>, a: [T], b: [T]) -> [T] {
25-
let rs: [T] = [];
26-
let a_len: uint = len::<T>(a);
27-
let a_ix: uint = 0u;
28-
let b_len: uint = len::<T>(b);
29-
let b_ix: uint = 0u;
43+
let rs = [];
44+
vec::reserve(rs, len(a) + len(b));
45+
let a_len = len(a);
46+
let a_ix = 0u;
47+
let b_len = len(b);
48+
let b_ix = 0u;
3049
while a_ix < a_len && b_ix < b_len {
3150
if le(a[a_ix], b[b_ix]) {
3251
rs += [a[a_ix]];
3352
a_ix += 1u;
3453
} else { rs += [b[b_ix]]; b_ix += 1u; }
3554
}
36-
rs += slice::<T>(a, a_ix, a_len);
37-
rs += slice::<T>(b, b_ix, b_len);
55+
rs += vec::slice(a, a_ix, a_len);
56+
rs += vec::slice(b, b_ix, b_len);
3857
ret rs;
3958
}
40-
let v_len: uint = len::<T>(v);
41-
if v_len == 0u { ret []; }
42-
if v_len == 1u { ret [v[0]]; }
43-
let mid: uint = v_len / 2u;
44-
let a: [T] = slice::<T>(v, 0u, mid);
45-
let b: [T] = slice::<T>(v, mid, v_len);
46-
ret merge::<T>(le, merge_sort::<T>(le, a), merge_sort::<T>(le, b));
4759
}
4860

4961
fn part<T: copy>(compare_func: le<T>, arr: [mutable T], left: uint,

0 commit comments

Comments
 (0)