1
Fork 0

Rollup merge of #49525 - varkor:sort_by_cached_key-conversion, r=scottmcm

Use sort_by_cached_key where appropriate

A follow-up to https://github.com/rust-lang/rust/pull/48639, converting various slice sorting calls to `sort_by_cached_key` when the key functions are more expensive.
This commit is contained in:
kennytm 2018-04-11 19:56:41 +08:00 committed by GitHub
commit 77777b4528
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 33 additions and 34 deletions

View file

@ -1400,6 +1400,7 @@ impl<T> [T] {
let sz_usize = mem::size_of::<(K, usize)>(); let sz_usize = mem::size_of::<(K, usize)>();
let len = self.len(); let len = self.len();
if len < 2 { return }
if sz_u8 < sz_u16 && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } if sz_u8 < sz_u16 && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) }
if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) }
if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) }

View file

@ -60,6 +60,7 @@
#![feature(refcell_replace_swap)] #![feature(refcell_replace_swap)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(slice_sort_by_cached_key)]
#![feature(specialization)] #![feature(specialization)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(trace_macros)] #![feature(trace_macros)]

View file

@ -401,7 +401,7 @@ pub fn used_crates(tcx: TyCtxt, prefer: LinkagePreference)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut ordering = tcx.postorder_cnums(LOCAL_CRATE); let mut ordering = tcx.postorder_cnums(LOCAL_CRATE);
Lrc::make_mut(&mut ordering).reverse(); Lrc::make_mut(&mut ordering).reverse();
libs.sort_by_key(|&(a, _)| { libs.sort_by_cached_key(|&(a, _)| {
ordering.iter().position(|x| *x == a) ordering.iter().position(|x| *x == a)
}); });
libs libs

View file

@ -22,6 +22,7 @@
#![cfg_attr(unix, feature(libc))] #![cfg_attr(unix, feature(libc))]
#![feature(quote)] #![feature(quote)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(set_stdio)] #![feature(set_stdio)]
#![feature(rustc_stack_internals)] #![feature(rustc_stack_internals)]
@ -82,7 +83,6 @@ use rustc_trans_utils::trans_crate::TransCrate;
use serialize::json::ToJson; use serialize::json::ToJson;
use std::any::Any; use std::any::Any;
use std::cmp::Ordering::Equal;
use std::cmp::max; use std::cmp::max;
use std::default::Default; use std::default::Default;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
@ -1176,13 +1176,8 @@ Available lint options:
fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
lints.sort_by(|x: &&Lint, y: &&Lint| { // The sort doesn't case-fold but it's doubtful we care.
match x.default_level(sess).cmp(&y.default_level(sess)) { lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name));
// The sort doesn't case-fold but it's doubtful we care.
Equal => x.name.cmp(y.name),
r => r,
}
});
lints lints
} }

View file

@ -1414,7 +1414,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
let mut all_impls: Vec<_> = visitor.impls.into_iter().collect(); let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
// Bring everything into deterministic order for hashing // Bring everything into deterministic order for hashing
all_impls.sort_unstable_by_key(|&(trait_def_id, _)| { all_impls.sort_by_cached_key(|&(trait_def_id, _)| {
tcx.def_path_hash(trait_def_id) tcx.def_path_hash(trait_def_id)
}); });
@ -1422,7 +1422,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
.into_iter() .into_iter()
.map(|(trait_def_id, mut impls)| { .map(|(trait_def_id, mut impls)| {
// Bring everything into deterministic order for hashing // Bring everything into deterministic order for hashing
impls.sort_unstable_by_key(|&def_index| { impls.sort_by_cached_key(|&def_index| {
tcx.hir.definitions().def_path_hash(def_index) tcx.hir.definitions().def_path_hash(def_index)
}); });

View file

@ -20,6 +20,7 @@
#![feature(macro_lifetime_matcher)] #![feature(macro_lifetime_matcher)]
#![feature(quote)] #![feature(quote)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(specialization)] #![feature(specialization)]
#![feature(rustc_private)] #![feature(rustc_private)]

View file

@ -15,6 +15,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
*/ */
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(slice_sort_by_cached_key)]
#![feature(from_ref)] #![feature(from_ref)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(box_syntax)] #![feature(box_syntax)]

View file

@ -112,11 +112,11 @@ use rustc::ty::{self, TyCtxt, InstanceDef};
use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::util::nodemap::{FxHashMap, FxHashSet};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::cmp;
use syntax::ast::NodeId; use syntax::ast::NodeId;
use syntax::symbol::{Symbol, InternedString}; use syntax::symbol::{Symbol, InternedString};
use rustc::mir::mono::MonoItem; use rustc::mir::mono::MonoItem;
use monomorphize::item::{MonoItemExt, InstantiationMode}; use monomorphize::item::{MonoItemExt, InstantiationMode};
use core::usize;
pub use rustc::mir::mono::CodegenUnit; pub use rustc::mir::mono::CodegenUnit;
@ -189,11 +189,9 @@ pub trait CodegenUnitExt<'tcx> {
}, item.symbol_name(tcx)) }, item.symbol_name(tcx))
} }
let items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect(); let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
let mut items : Vec<_> = items.iter() items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
.map(|il| (il, item_sort_key(tcx, il.0))).collect(); items
items.sort_by(|&(_, ref key1), &(_, ref key2)| key1.cmp(key2));
items.into_iter().map(|(&item_linkage, _)| item_linkage).collect()
} }
} }
@ -509,7 +507,7 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
// Merge the two smallest codegen units until the target size is reached. // Merge the two smallest codegen units until the target size is reached.
while codegen_units.len() > target_cgu_count { while codegen_units.len() > target_cgu_count {
// Sort small cgus to the back // Sort small cgus to the back
codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
let mut smallest = codegen_units.pop().unwrap(); let mut smallest = codegen_units.pop().unwrap();
let second_smallest = codegen_units.last_mut().unwrap(); let second_smallest = codegen_units.last_mut().unwrap();

View file

@ -13,6 +13,7 @@
html_root_url = "https://doc.rust-lang.org/nightly/")] html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#[macro_use] #[macro_use]
extern crate log; extern crate log;
@ -1149,13 +1150,9 @@ impl<'a> ModuleData<'a> {
fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) { fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
let resolutions = self.resolutions.borrow(); let resolutions = self.resolutions.borrow();
let mut resolutions = resolutions.iter().map(|(&(ident, ns), &resolution)| { let mut resolutions = resolutions.iter().collect::<Vec<_>>();
// Pre-compute keys for sorting resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.name.as_str(), ns));
(ident.name.as_str(), ns, ident, resolution) for &(&(ident, ns), &resolution) in resolutions.iter() {
})
.collect::<Vec<_>>();
resolutions.sort_unstable_by_key(|&(str, ns, ..)| (str, ns));
for &(_, ns, ident, resolution) in resolutions.iter() {
resolution.borrow().binding.map(|binding| f(ident, ns, binding)); resolution.borrow().binding.map(|binding| f(ident, ns, binding));
} }
} }
@ -3340,7 +3337,9 @@ impl<'a> Resolver<'a> {
let is_mod = |def| match def { Def::Mod(..) => true, _ => false }; let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
let mut candidates = let mut candidates =
self.lookup_import_candidates(name, TypeNS, is_mod); self.lookup_import_candidates(name, TypeNS, is_mod);
candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string())); candidates.sort_by_cached_key(|c| {
(c.path.segments.len(), c.path.to_string())
});
if let Some(candidate) = candidates.get(0) { if let Some(candidate) = candidates.get(0) {
format!("Did you mean `{}`?", candidate.path) format!("Did you mean `{}`?", candidate.path)
} else { } else {
@ -3578,7 +3577,7 @@ impl<'a> Resolver<'a> {
let name = path[path.len() - 1].name; let name = path[path.len() - 1].name;
// Make sure error reporting is deterministic. // Make sure error reporting is deterministic.
names.sort_by_key(|name| name.as_str()); names.sort_by_cached_key(|name| name.as_str());
match find_best_match_for_name(names.iter(), &name.as_str(), None) { match find_best_match_for_name(names.iter(), &name.as_str(), None) {
Some(found) if found != name => Some(found), Some(found) if found != name => Some(found),
_ => None, _ => None,

View file

@ -82,7 +82,8 @@ use std::ffi::CString;
use std::str; use std::str;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use std::{i32, usize}; use std::i32;
use std::cmp;
use std::sync::mpsc; use std::sync::mpsc;
use syntax_pos::Span; use syntax_pos::Span;
use syntax_pos::symbol::InternedString; use syntax_pos::symbol::InternedString;
@ -830,7 +831,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// a bit more efficiently. // a bit more efficiently.
let codegen_units = { let codegen_units = {
let mut codegen_units = codegen_units; let mut codegen_units = codegen_units;
codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
codegen_units codegen_units
}; };

View file

@ -26,6 +26,7 @@
#![feature(libc)] #![feature(libc)]
#![feature(quote)] #![feature(quote)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(optin_builtin_traits)] #![feature(optin_builtin_traits)]
#![feature(inclusive_range_fields)] #![feature(inclusive_range_fields)]
#![feature(underscore_lifetimes)] #![feature(underscore_lifetimes)]

View file

@ -799,7 +799,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
.collect(); .collect();
// sort them by the name so we have a stable result // sort them by the name so we have a stable result
names.sort_by_key(|n| n.as_str()); names.sort_by_cached_key(|n| n.as_str());
names names
} }

View file

@ -81,6 +81,7 @@ This API is completely unstable and subject to change.
#![feature(refcell_replace_swap)] #![feature(refcell_replace_swap)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(slice_sort_by_cached_key)]
#![feature(dyn_trait)] #![feature(dyn_trait)]
#[macro_use] extern crate log; #[macro_use] extern crate log;

View file

@ -1437,9 +1437,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
// involved (impls rarely have more than a few bounds) means that it // involved (impls rarely have more than a few bounds) means that it
// shouldn't matter in practice. // shouldn't matter in practice.
fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) { fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
vec.sort_unstable_by(|first, second| { vec.sort_by_cached_key(|x| format!("{:?}", x))
format!("{:?}", first).cmp(&format!("{:?}", second))
});
} }
fn is_fn_ty(&self, tcx: &TyCtxt, ty: &Type) -> bool { fn is_fn_ty(&self, tcx: &TyCtxt, ty: &Type) -> bool {

View file

@ -19,6 +19,7 @@
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(fs_read_write)] #![feature(fs_read_write)]
#![feature(set_stdio)] #![feature(set_stdio)]
#![feature(slice_sort_by_cached_key)]
#![feature(test)] #![feature(test)]
#![feature(unicode)] #![feature(unicode)]
#![feature(vec_remove_item)] #![feature(vec_remove_item)]

View file

@ -21,6 +21,7 @@
#![feature(unicode)] #![feature(unicode)]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(non_exhaustive)] #![feature(non_exhaustive)]
#![feature(const_atomic_usize_new)] #![feature(const_atomic_usize_new)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]

View file

@ -689,7 +689,7 @@ impl<'a> Parser<'a> {
.chain(inedible.iter().map(|x| TokenType::Token(x.clone()))) .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
.chain(self.expected_tokens.iter().cloned()) .chain(self.expected_tokens.iter().cloned())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
expected.sort_by(|a, b| a.to_string().cmp(&b.to_string())); expected.sort_by_cached_key(|x| x.to_string());
expected.dedup(); expected.dedup();
let expect = tokens_to_string(&expected[..]); let expect = tokens_to_string(&expected[..]);
let actual = self.this_token_to_string(); let actual = self.this_token_to_string();