Skip to content

Commit 866a713

Browse files
committed
Auto merge of #52738 - ljedrz:push_to_extend, r=eddyb
Replace push loops with extend() where possible Or set the vector capacity where I couldn't do it. According to my [simple benchmark](https://gist.github.com/ljedrz/568e97621b749849684c1da71c27dceb) `extend`ing a vector can be over **10 times** faster than `push`ing to it in a loop: 10 elements (6.1 times faster): ``` test bench_extension ... bench: 75 ns/iter (+/- 23) test bench_push_loop ... bench: 458 ns/iter (+/- 142) ``` 100 elements (11.12 times faster): ``` test bench_extension ... bench: 87 ns/iter (+/- 26) test bench_push_loop ... bench: 968 ns/iter (+/- 3,528) ``` 1000 elements (11.04 times faster): ``` test bench_extension ... bench: 311 ns/iter (+/- 9) test bench_push_loop ... bench: 3,436 ns/iter (+/- 233) ``` Seems like a good idea to use `extend` as much as possible.
2 parents 70cac59 + 59c8a27 commit 866a713

File tree

28 files changed

+101
-150
lines changed

28 files changed

+101
-150
lines changed

src/bootstrap/util.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ pub fn push_exe_path(mut buf: PathBuf, components: &[&str]) -> PathBuf {
9292
file.push_str(".exe");
9393
}
9494

95-
for c in components {
96-
buf.push(c);
97-
}
98-
95+
buf.extend(components);
9996
buf.push(file);
10097

10198
buf

src/librustc/cfg/construct.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -567,12 +567,12 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
567567
fn add_returning_edge(&mut self,
568568
_from_expr: &hir::Expr,
569569
from_index: CFGIndex) {
570-
let mut data = CFGEdgeData {
571-
exiting_scopes: vec![],
570+
let data = CFGEdgeData {
571+
exiting_scopes: self.loop_scopes.iter()
572+
.rev()
573+
.map(|&LoopScope { loop_id: id, .. }| id)
574+
.collect()
572575
};
573-
for &LoopScope { loop_id: id, .. } in self.loop_scopes.iter().rev() {
574-
data.exiting_scopes.push(id);
575-
}
576576
self.graph.add_edge(from_index, self.fn_exit, data);
577577
}
578578

src/librustc/infer/outlives/obligations.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
151151
debug!("process_registered_region_obligations()");
152152

153153
// pull out the region obligations with the given `body_id` (leaving the rest)
154-
let mut my_region_obligations = Vec::with_capacity(self.region_obligations.borrow().len());
155-
{
154+
let my_region_obligations = {
156155
let mut r_o = self.region_obligations.borrow_mut();
157-
for (_, obligation) in r_o.drain_filter(|(ro_body_id, _)| *ro_body_id == body_id) {
158-
my_region_obligations.push(obligation);
159-
}
160-
}
156+
let my_r_o = r_o.drain_filter(|(ro_body_id, _)| *ro_body_id == body_id)
157+
.map(|(_, obligation)| obligation).collect::<Vec<_>>();
158+
my_r_o
159+
};
161160

162161
let outlives = &mut TypeOutlives::new(
163162
self,

src/librustc/middle/reachable.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
367367
// We need only trait impls here, not inherent impls, and only non-exported ones
368368
if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node {
369369
if !self.access_levels.is_reachable(item.id) {
370-
for impl_item_ref in impl_item_refs {
371-
self.worklist.push(impl_item_ref.id.node_id);
372-
}
370+
self.worklist.extend(impl_item_refs.iter().map(|r| r.id.node_id));
373371

374372
let trait_def_id = match trait_ref.path.def {
375373
Def::Trait(def_id) => def_id,
@@ -426,9 +424,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
426424
// If other crates link to us, they're going to expect to be able to
427425
// use the lang items, so we need to be sure to mark them as
428426
// exported.
429-
for (id, _) in &access_levels.map {
430-
reachable_context.worklist.push(*id);
431-
}
427+
reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
432428
for item in tcx.lang_items().items().iter() {
433429
if let Some(did) = *item {
434430
if let Some(node_id) = tcx.hir.as_local_node_id(did) {

src/librustc/mir/traversal.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
6464
let data = &self.mir[idx];
6565

6666
if let Some(ref term) = data.terminator {
67-
for &succ in term.successors() {
68-
self.worklist.push(succ);
69-
}
67+
self.worklist.extend(term.successors());
7068
}
7169

7270
return Some((idx, data));

src/librustc/session/config.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -899,9 +899,7 @@ macro_rules! options {
899899
-> bool {
900900
match v {
901901
Some(s) => {
902-
for s in s.split_whitespace() {
903-
slot.push(s.to_string());
904-
}
902+
slot.extend(s.split_whitespace().map(|s| s.to_string()));
905903
true
906904
},
907905
None => false,

src/librustc/traits/specialize/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option<String> {
438438
}
439439
pretty_predicates.push(p.to_string());
440440
}
441-
for ty in types_without_default_bounds {
442-
pretty_predicates.push(format!("{}: ?Sized", ty));
443-
}
441+
pretty_predicates.extend(
442+
types_without_default_bounds.iter().map(|ty| format!("{}: ?Sized", ty))
443+
);
444444
if !pretty_predicates.is_empty() {
445445
write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap();
446446
}

src/librustc_codegen_llvm/back/rpath.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,7 @@ fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
152152
(Some(_), Some(b)) if b == Component::ParentDir => return None,
153153
(Some(a), Some(_)) => {
154154
comps.push(Component::ParentDir);
155-
for _ in itb {
156-
comps.push(Component::ParentDir);
157-
}
155+
comps.extend(itb.map(|_| Component::ParentDir));
158156
comps.push(a);
159157
comps.extend(ita.by_ref());
160158
break;

src/librustc_codegen_llvm/debuginfo/metadata.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc::util::common::path2cstr;
3939
use libc::{c_uint, c_longlong};
4040
use std::ffi::CString;
4141
use std::fmt::Write;
42+
use std::iter;
4243
use std::ptr;
4344
use std::path::{Path, PathBuf};
4445
use syntax::ast;
@@ -364,18 +365,16 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
364365
&signature,
365366
);
366367

367-
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
368-
369-
// return type
370-
signature_metadata.push(match signature.output().sty {
371-
ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
372-
_ => type_metadata(cx, signature.output(), span)
373-
});
374-
375-
// regular arguments
376-
for &argument_type in signature.inputs() {
377-
signature_metadata.push(type_metadata(cx, argument_type, span));
378-
}
368+
let signature_metadata: Vec<DIType> = iter::once(
369+
// return type
370+
match signature.output().sty {
371+
ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
372+
_ => type_metadata(cx, signature.output(), span)
373+
}
374+
).chain(
375+
// regular arguments
376+
signature.inputs().iter().map(|argument_type| type_metadata(cx, argument_type, span))
377+
).collect();
379378

380379
return_if_metadata_created_in_meantime!(cx, unique_type_id);
381380

src/librustc_codegen_llvm/debuginfo/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
352352

353353
if sig.abi == Abi::RustCall && !sig.inputs().is_empty() {
354354
if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
355-
for &argument_type in args {
356-
signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP));
357-
}
355+
signature.extend(
356+
args.iter().map(|argument_type|
357+
type_metadata(cx, argument_type, syntax_pos::DUMMY_SP))
358+
);
358359
}
359360
}
360361

0 commit comments

Comments
 (0)