-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Mention [T]::sort is stable in docs #29579
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
@steveklabnik Should this expound on stability or link to an external definition of it (e.g. https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)? Or is that overkill? |
@apasel422 for now, it's overkill. I have metabugs to overhaul all of these docs, I'll be doing that kind of extra work at that point. It's easier when you're doing big chunks at one time. |
I think stability of sort algorithm is a well known concept that needs no introduction. |
@bors: r- Ah if ok I'd like to run this by the libs team, this is a pretty big guarantee to provide and I know we've talked about this in the past one way or another. I forget the exact outcome, but I vaguely remember us explicitly wanting to not guarantee it's not stable, but now I may also be misremembering! |
Yeah, given the discussion, it looked like it already was. No worries on waiting though, would rather have it double checked than not! |
I distinctly remember us intending to guarantee stability. Otherwise we should be using quicksort with some decent rng (the n^2 behaviour is inconceivable with proper rng). |
FWIW,
Having an RNG/global state (it would presumably need thread locals, and maybe even seeding from some source?) would probably make the sort inappropriate for low-level use-cases, and it'd be great if sorts worked in as many places as possible. |
Maybe I'm misunderstanding, but why use thread locals? Just get a new seed from the OS or whatever on every call to sort that isn't small enough to warrant insertionsort. Since it's already an incredibly expensive op, that would be a drop in the bucket, I think? But yes, a libcore-friendly sort would be best (wikisort, I guess?) |
Sorting isn't that expensive. It's certainly going to be a drop in the bucket for a very long sort, but it won't be so small for moderate lengths, which can totally happen in tight loops (e.g. a whole pile of vectors with length less than 1000 that each need to be sorted). #![feature(test, read_exact)]
extern crate rand;
extern crate test;
use std::io::prelude::*;
use std::fs;
use rand::Rng;
#[bench]
fn os_rng_u32(b: &mut test::Bencher) {
b.iter(|| {
rand::OsRng::new().unwrap().gen::<u32>();
})
}
#[bench]
fn read_dev_urandom_u32(b: &mut test::Bencher) {
b.iter(|| {
let mut b = [0; 4];
fs::File::open("/dev/urandom").unwrap().read_exact(&mut b).unwrap();
})
}
#[bench]
fn sort_0050(b: &mut test::Bencher) {
let v = rand::thread_rng().gen_iter::<u32>().take(50).collect::<Vec<_>>();
b.iter(|| {
v.clone().sort();
})
}
#[bench]
fn sort_0100(b: &mut test::Bencher) {
let v = rand::thread_rng().gen_iter::<u32>().take(100).collect::<Vec<_>>();
b.iter(|| {
v.clone().sort();
})
}
#[bench]
fn sort_0500(b: &mut test::Bencher) {
let v = rand::thread_rng().gen_iter::<u32>().take(500).collect::<Vec<_>>();
b.iter(|| {
v.clone().sort();
})
}
#[bench]
fn sort_1000(b: &mut test::Bencher) {
let v = rand::thread_rng().gen_iter::<u32>().take(1000).collect::<Vec<_>>();
b.iter(|| {
v.clone().sort();
})
}
Also, random functions doing "random" (hah) syscalls is unfortunate from a sandboxing point of view. (I guess ones related to randomness are probably going to generally have to be whitelisted anyway, though, just like ones for allocation.) |
Fixes #27322