Skip to content

Commit

Permalink
auto merge of #11064 : huonw/rust/vec-sort, r=alexcrichton
Browse files Browse the repository at this point in the history
This uses quite a bit of unsafe code for speed and failure safety, and allocates `2*n` temporary storage.

[Performance](https://gist.github.com/huonw/5547f2478380288a28c2):

|      n |      new | priority_queue |   quick3 |
|-------:|---------:|---------------:|---------:|
|      5 |      200 |            155 |      106 |
|    100 |     6490 |           8750 |     5810 |
|  10000 |  1300000 |        1790000 |  1060000 |
| 100000 | 16700000 |       23600000 | 12700000 |
| sorted |   520000 |        1380000 | 53900000 |
|  trend |  1310000 |        1690000 |  1100000 |

(The times are in nanoseconds, having subtracted the set-up time (i.e. the `just_generate` bench target).)

I imagine that there is still significant room for improvement, particularly because both priority_queue and quick3 are doing a static call via `Ord` or `TotalOrd` for the comparisons, while this is using a (boxed) closure.

Also, this code does not `clone`, unlike `quick_sort3`; and is stable, unlike both of the others.
  • Loading branch information
bors committed Dec 22, 2013
2 parents cd13f4d + 645fff4 commit 55cbef6
Show file tree
Hide file tree
Showing 19 changed files with 493 additions and 1,303 deletions.
8 changes: 2 additions & 6 deletions src/libextra/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ use std::io;
use std::io::fs;
use std::path::is_sep;

use sort;

/**
* An iterator that yields Paths from the filesystem that match a particular
* pattern - see the `glob` function for more details.
Expand Down Expand Up @@ -149,9 +147,8 @@ impl Iterator<Path> for GlobIterator {

fn list_dir_sorted(path: &Path) -> ~[Path] {
match io::result(|| fs::readdir(path)) {
Ok(children) => {
let mut children = children;
sort::quick_sort(children, |p1, p2| p2.filename() <= p1.filename());
Ok(mut children) => {
children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
children
}
Err(..) => ~[]
Expand Down Expand Up @@ -771,4 +768,3 @@ mod test {
assert!(Pattern::new("a/b").matches_path(&Path::new("a/b")));
}
}

2 changes: 0 additions & 2 deletions src/libextra/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ pub mod ringbuf;
pub mod priority_queue;
pub mod smallintmap;

pub mod sort;

pub mod dlist;
pub mod treemap;
pub mod btree;
Expand Down
15 changes: 9 additions & 6 deletions src/libextra/priority_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ impl<T: Ord> Extendable<T> for PriorityQueue<T> {

#[cfg(test)]
mod tests {
use sort::merge_sort;
use priority_queue::PriorityQueue;

#[test]
Expand All @@ -231,7 +230,8 @@ mod tests {
#[test]
fn test_top_and_pop() {
let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
let mut sorted = merge_sort(data, |x, y| x.le(y));
let mut sorted = data.clone();
sorted.sort();
let mut heap = PriorityQueue::from_vec(data);
while !heap.is_empty() {
assert_eq!(heap.top(), sorted.last());
Expand Down Expand Up @@ -311,11 +311,14 @@ mod tests {
assert_eq!(heap.len(), 5);
}

fn check_to_vec(data: ~[int]) {
fn check_to_vec(mut data: ~[int]) {
let heap = PriorityQueue::from_vec(data.clone());
assert_eq!(merge_sort(heap.clone().to_vec(), |x, y| x.le(y)),
merge_sort(data, |x, y| x.le(y)));
assert_eq!(heap.to_sorted_vec(), merge_sort(data, |x, y| x.le(y)));
let mut v = heap.clone().to_vec();
v.sort();
data.sort();

assert_eq!(v, data);
assert_eq!(heap.to_sorted_vec(), data);
}

#[test]
Expand Down
Loading

0 comments on commit 55cbef6

Please sign in to comment.