@@ -1301,33 +1301,76 @@ impl<T> [T] {
1301
1301
merge_sort ( self , |a, b| compare ( a, b) == Less ) ;
1302
1302
}
1303
1303
1304
+ /// Sorts the slice with a key extraction function.
1305
+ ///
1306
+ /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log m n)`
1307
+ /// worst-case, where the key function is `O(m)`.
1308
+ ///
1309
+ /// For expensive key functions (e.g. functions that are not simple property accesses or
1310
+ /// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be
1311
+ /// significantly faster, as it does not recompute element keys.
1312
+ ///
1313
+ /// When applicable, unstable sorting is preferred because it is generally faster than stable
1314
+ /// sorting and it doesn't allocate auxiliary memory.
1315
+ /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key).
1316
+ ///
1317
+ /// # Current implementation
1318
+ ///
1319
+ /// The current algorithm is an adaptive, iterative merge sort inspired by
1320
+ /// [timsort](https://en.wikipedia.org/wiki/Timsort).
1321
+ /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of
1322
+ /// two or more sorted sequences concatenated one after another.
1323
+ ///
1324
+ /// Also, it allocates temporary storage half the size of `self`, but for short slices a
1325
+ /// non-allocating insertion sort is used instead.
1326
+ ///
1327
+ /// # Examples
1328
+ ///
1329
+ /// ```
1330
+ /// let mut v = [-5i32, 4, 1, -3, 2];
1331
+ ///
1332
+ /// v.sort_by_key(|k| k.abs());
1333
+ /// assert!(v == [1, 2, -3, 4, -5]);
1334
+ /// ```
1335
+ #[ stable( feature = "slice_sort_by_key" , since = "1.7.0" ) ]
1336
+ #[ inline]
1337
+ pub fn sort_by_key < K , F > ( & mut self , mut f : F )
1338
+ where F : FnMut ( & T ) -> K , K : Ord
1339
+ {
1340
+ merge_sort ( self , |a, b| f ( a) . lt ( & f ( b) ) ) ;
1341
+ }
1342
+
1304
1343
/// Sorts the slice with a key extraction function.
1305
1344
///
1306
1345
/// During sorting, the key function is called only once per element.
1307
1346
///
1308
1347
/// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)`
1309
1348
/// worst-case, where the key function is `O(m)`.
1310
1349
///
1350
+ /// For simple key functions (e.g. functions that are property accesses or
1351
+ /// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be
1352
+ /// faster.
1353
+ ///
1311
1354
/// # Current implementation
1312
1355
///
1313
1356
/// The current algorithm is an adaptive, iterative merge sort inspired by
1314
1357
/// [timsort](https://en.wikipedia.org/wiki/Timsort).
1315
1358
/// It is designed to be very fast in cases where the slice is nearly sorted, or consists of
1316
1359
/// two or more sorted sequences concatenated one after another.
1317
1360
///
1318
- /// The algorithm allocates temporary storage in a `Vec<(K, usize)` the length of the slice.
1361
+ /// The algorithm allocates temporary storage in a `Vec<(K, usize)> ` the length of the slice.
1319
1362
///
1320
1363
/// # Examples
1321
1364
///
1322
1365
/// ```
1323
1366
/// let mut v = [-5i32, 4, 1, -3, 2];
1324
1367
///
1325
- /// v.sort_by_key (|k| k.abs());
1368
+ /// v.sort_by_cached_key (|k| k.abs());
1326
1369
/// assert!(v == [1, 2, -3, 4, -5]);
1327
1370
/// ```
1328
- #[ stable ( feature = "slice_sort_by_key " , since = "1.7.0 " ) ]
1371
+ #[ unstable ( feature = "slice_sort_by_uncached_key " , issue = "34447 " ) ]
1329
1372
#[ inline]
1330
- pub fn sort_by_key < K , F > ( & mut self , f : F )
1373
+ pub fn sort_by_cached_key < K , F > ( & mut self , f : F )
1331
1374
where F : FnMut ( & T ) -> K , K : Ord
1332
1375
{
1333
1376
// Helper macro for indexing our vector by the smallest possible type, to reduce allocation.
@@ -1432,9 +1475,6 @@ impl<T> [T] {
1432
1475
/// Sorts the slice with a key extraction function, but may not preserve the order of equal
1433
1476
/// elements.
1434
1477
///
1435
- /// Note that, currently, the key function for [`sort_unstable_by_key`] is called multiple times
1436
- /// per element, unlike [`sort_by_key`].
1437
- ///
1438
1478
/// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
1439
1479
/// and `O(m n log m n)` worst-case, where the key function is `O(m)`.
1440
1480
///
@@ -1446,8 +1486,9 @@ impl<T> [T] {
1446
1486
/// randomization to avoid degenerate cases, but with a fixed seed to always provide
1447
1487
/// deterministic behavior.
1448
1488
///
1449
- /// Due to its key calling strategy, [`sort_unstable_by_key`] is likely to be slower than
1450
- /// [`sort_by_key`] in cases where the key function is expensive.
1489
+ /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key)
1490
+ /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_uncached_key) in
1491
+ /// cases where the key function is expensive.
1451
1492
///
1452
1493
/// # Examples
1453
1494
///
@@ -1458,8 +1499,6 @@ impl<T> [T] {
1458
1499
/// assert!(v == [1, 2, -3, 4, -5]);
1459
1500
/// ```
1460
1501
///
1461
- /// [`sort_by_key`]: #method.sort_by_key
1462
- /// [`sort_unstable_by_key`]: #method.sort_unstable_by_key
1463
1502
/// [pdqsort]: https://github.com/orlp/pdqsort
1464
1503
#[ stable( feature = "sort_unstable" , since = "1.20.0" ) ]
1465
1504
#[ inline]
0 commit comments