about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-03-01 10:46:06 +0000
committervarkor <github@varkor.com>2018-03-16 13:57:07 +0000
commitea6a1bdf6ba754f3b96e3a46f9173b17ff18ed07 (patch)
treed10cc0401caf55a84bff1adb41b748625c94298b /src/liballoc
parentff2d506c2c748bd218f74c6014abc4cecc8c74c4 (diff)
downloadrust-ea6a1bdf6ba754f3b96e3a46f9173b17ff18ed07.tar.gz
rust-ea6a1bdf6ba754f3b96e3a46f9173b17ff18ed07.zip
Compute each key only one during slice::sort_by_key
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/slice.rs12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index dc40062ef13..c57f1e7f572 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -1328,10 +1328,18 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "slice_sort_by_key", since = "1.7.0")]
     #[inline]
-    pub fn sort_by_key<B, F>(&mut self, mut f: F)
+    pub fn sort_by_key<B, F>(&mut self, f: F)
         where F: FnMut(&T) -> B, B: Ord
     {
-        merge_sort(self, |a, b| f(a).lt(&f(b)));
+        let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect();
+        indices.sort();
+        for i in 0..self.len() {
+            let mut index = indices[i].1;
+            while index < i {
+                index = indices[index].1;
+            }
+            self.swap(i, index);
+        }
     }
 
     /// Sorts the slice, but may not preserve the order of equal elements.