mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Auto merge of #43010 - stjepang:stabilize-sort-unstable, r=alexcrichton
Stabilize feature sort_unstable Closes #40585
This commit is contained in:
commit
1d2db7b9e8
@ -1,40 +0,0 @@
|
|||||||
# `sort_unstable`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#40585]
|
|
||||||
|
|
||||||
[#40585]: https://github.com/rust-lang/rust/issues/40585
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The default `sort` method on slices is stable. In other words, it guarantees
|
|
||||||
that the original order of equal elements is preserved after sorting. The
|
|
||||||
method has several undesirable characteristics:
|
|
||||||
|
|
||||||
1. It allocates a sizable chunk of memory.
|
|
||||||
2. If you don't need stability, it is not as performant as it could be.
|
|
||||||
|
|
||||||
An alternative is the new `sort_unstable` feature, which includes these
|
|
||||||
methods for sorting slices:
|
|
||||||
|
|
||||||
1. `sort_unstable`
|
|
||||||
2. `sort_unstable_by`
|
|
||||||
3. `sort_unstable_by_key`
|
|
||||||
|
|
||||||
Unstable sorting is generally faster and makes no allocations. The majority
|
|
||||||
of real-world sorting needs doesn't require stability, so these methods can
|
|
||||||
very often come in handy.
|
|
||||||
|
|
||||||
Another important difference is that `sort` lives in `libstd` and
|
|
||||||
`sort_unstable` lives in `libcore`. The reason is that the former makes
|
|
||||||
allocations and the latter doesn't.
|
|
||||||
|
|
||||||
A simple example:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(sort_unstable)]
|
|
||||||
|
|
||||||
let mut v = [-5, 4, 1, -3, 2];
|
|
||||||
|
|
||||||
v.sort_unstable();
|
|
||||||
assert!(v == [-5, -3, 1, 2, 4]);
|
|
||||||
```
|
|
@ -14,7 +14,6 @@
|
|||||||
#![feature(rand)]
|
#![feature(rand)]
|
||||||
#![feature(repr_simd)]
|
#![feature(repr_simd)]
|
||||||
#![feature(slice_rotate)]
|
#![feature(slice_rotate)]
|
||||||
#![feature(sort_unstable)]
|
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
@ -83,7 +83,6 @@
|
|||||||
#![cfg_attr(not(test), feature(core_float))]
|
#![cfg_attr(not(test), feature(core_float))]
|
||||||
#![cfg_attr(not(test), feature(exact_size_is_empty))]
|
#![cfg_attr(not(test), feature(exact_size_is_empty))]
|
||||||
#![cfg_attr(not(test), feature(slice_rotate))]
|
#![cfg_attr(not(test), feature(slice_rotate))]
|
||||||
#![cfg_attr(not(test), feature(sort_unstable))]
|
|
||||||
#![cfg_attr(not(test), feature(str_checked_slicing))]
|
#![cfg_attr(not(test), feature(str_checked_slicing))]
|
||||||
#![cfg_attr(test, feature(rand, test))]
|
#![cfg_attr(test, feature(rand, test))]
|
||||||
#![feature(allocator)]
|
#![feature(allocator)]
|
||||||
|
@ -1144,6 +1144,10 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
||||||
///
|
///
|
||||||
|
/// When applicable, unstable sorting is preferred because it is generally faster than stable
|
||||||
|
/// sorting and it doesn't allocate auxiliary memory.
|
||||||
|
/// See [`sort_unstable`](#method.sort_unstable).
|
||||||
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
||||||
@ -1174,6 +1178,10 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
||||||
///
|
///
|
||||||
|
/// When applicable, unstable sorting is preferred because it is generally faster than stable
|
||||||
|
/// sorting and it doesn't allocate auxiliary memory.
|
||||||
|
/// See [`sort_unstable_by`](#method.sort_unstable_by).
|
||||||
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
||||||
@ -1207,6 +1215,10 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
|
||||||
///
|
///
|
||||||
|
/// When applicable, unstable sorting is preferred because it is generally faster than stable
|
||||||
|
/// sorting and it doesn't allocate auxiliary memory.
|
||||||
|
/// See [`sort_unstable_by_key`](#method.sort_unstable_by_key).
|
||||||
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
/// The current algorithm is an adaptive, iterative merge sort inspired by
|
||||||
@ -1251,8 +1263,6 @@ impl<T> [T] {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(sort_unstable)]
|
|
||||||
///
|
|
||||||
/// let mut v = [-5, 4, 1, -3, 2];
|
/// let mut v = [-5, 4, 1, -3, 2];
|
||||||
///
|
///
|
||||||
/// v.sort_unstable();
|
/// v.sort_unstable();
|
||||||
@ -1260,8 +1270,7 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [pdqsort]: https://github.com/orlp/pdqsort
|
/// [pdqsort]: https://github.com/orlp/pdqsort
|
||||||
// FIXME #40585: Mention `sort_unstable` in the documentation for `sort`.
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_unstable(&mut self)
|
pub fn sort_unstable(&mut self)
|
||||||
where T: Ord
|
where T: Ord
|
||||||
@ -1288,8 +1297,6 @@ impl<T> [T] {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(sort_unstable)]
|
|
||||||
///
|
|
||||||
/// let mut v = [5, 4, 1, 3, 2];
|
/// let mut v = [5, 4, 1, 3, 2];
|
||||||
/// v.sort_unstable_by(|a, b| a.cmp(b));
|
/// v.sort_unstable_by(|a, b| a.cmp(b));
|
||||||
/// assert!(v == [1, 2, 3, 4, 5]);
|
/// assert!(v == [1, 2, 3, 4, 5]);
|
||||||
@ -1300,8 +1307,7 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [pdqsort]: https://github.com/orlp/pdqsort
|
/// [pdqsort]: https://github.com/orlp/pdqsort
|
||||||
// FIXME #40585: Mention `sort_unstable_by` in the documentation for `sort_by`.
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_unstable_by<F>(&mut self, compare: F)
|
pub fn sort_unstable_by<F>(&mut self, compare: F)
|
||||||
where F: FnMut(&T, &T) -> Ordering
|
where F: FnMut(&T, &T) -> Ordering
|
||||||
@ -1328,8 +1334,6 @@ impl<T> [T] {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(sort_unstable)]
|
|
||||||
///
|
|
||||||
/// let mut v = [-5i32, 4, 1, -3, 2];
|
/// let mut v = [-5i32, 4, 1, -3, 2];
|
||||||
///
|
///
|
||||||
/// v.sort_unstable_by_key(|k| k.abs());
|
/// v.sort_unstable_by_key(|k| k.abs());
|
||||||
@ -1337,8 +1341,7 @@ impl<T> [T] {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [pdqsort]: https://github.com/orlp/pdqsort
|
/// [pdqsort]: https://github.com/orlp/pdqsort
|
||||||
// FIXME #40585: Mention `sort_unstable_by_key` in the documentation for `sort_by_key`.
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
|
pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
|
||||||
where F: FnMut(&T) -> B,
|
where F: FnMut(&T) -> B,
|
||||||
|
@ -212,15 +212,15 @@ pub trait SliceExt {
|
|||||||
#[stable(feature = "copy_from_slice", since = "1.9.0")]
|
#[stable(feature = "copy_from_slice", since = "1.9.0")]
|
||||||
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
|
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
|
||||||
|
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
fn sort_unstable(&mut self)
|
fn sort_unstable(&mut self)
|
||||||
where Self::Item: Ord;
|
where Self::Item: Ord;
|
||||||
|
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
fn sort_unstable_by<F>(&mut self, compare: F)
|
fn sort_unstable_by<F>(&mut self, compare: F)
|
||||||
where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
|
where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
|
||||||
|
|
||||||
#[unstable(feature = "sort_unstable", issue = "40585")]
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
||||||
fn sort_unstable_by_key<B, F>(&mut self, f: F)
|
fn sort_unstable_by_key<B, F>(&mut self, f: F)
|
||||||
where F: FnMut(&Self::Item) -> B,
|
where F: FnMut(&Self::Item) -> B,
|
||||||
B: Ord;
|
B: Ord;
|
||||||
|
@ -351,7 +351,7 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
|
|||||||
|
|
||||||
if start_l < end_l {
|
if start_l < end_l {
|
||||||
// The left block remains.
|
// The left block remains.
|
||||||
// Move it's remaining out-of-order elements to the far right.
|
// Move its remaining out-of-order elements to the far right.
|
||||||
debug_assert_eq!(width(l, r), block_l);
|
debug_assert_eq!(width(l, r), block_l);
|
||||||
while start_l < end_l {
|
while start_l < end_l {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -363,7 +363,7 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
|
|||||||
width(v.as_mut_ptr(), r)
|
width(v.as_mut_ptr(), r)
|
||||||
} else if start_r < end_r {
|
} else if start_r < end_r {
|
||||||
// The right block remains.
|
// The right block remains.
|
||||||
// Move it's remaining out-of-order elements to the far left.
|
// Move its remaining out-of-order elements to the far left.
|
||||||
debug_assert_eq!(width(l, r), block_r);
|
debug_assert_eq!(width(l, r), block_r);
|
||||||
while start_r < end_r {
|
while start_r < end_r {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(slice_rotate)]
|
#![feature(slice_rotate)]
|
||||||
#![feature(sort_internals)]
|
#![feature(sort_internals)]
|
||||||
#![feature(sort_unstable)]
|
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
#![feature(step_by)]
|
#![feature(step_by)]
|
||||||
#![feature(step_trait)]
|
#![feature(step_trait)]
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(discriminant_value)]
|
#![feature(discriminant_value)]
|
||||||
#![feature(sort_unstable)]
|
|
||||||
#![feature(trace_macros)]
|
#![feature(trace_macros)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#![feature(rand)]
|
#![feature(rand)]
|
||||||
#![feature(conservative_impl_trait)]
|
#![feature(conservative_impl_trait)]
|
||||||
#![feature(sort_unstable)]
|
|
||||||
|
|
||||||
extern crate graphviz;
|
extern crate graphviz;
|
||||||
#[macro_use] extern crate rustc;
|
#[macro_use] extern crate rustc;
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
#![feature(discriminant_value)]
|
#![feature(discriminant_value)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(sort_unstable)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
Loading…
Reference in New Issue
Block a user