Skip to content

Commit 83b67e2

Browse files
bors[bot]cuviper
andcommitted
673: Reduce the genericity of many closures r=nikomatsakis a=cuviper The `take_while` closure only needs to be generic in `T`, along with a captured `&AtomicBool`. When we write the closure directly, it carries all the type baggage of `WhileSomeFolder<'f, C>::consumer_iter<I>`, where the monomorphized type may explode. Instead, we can move this closure to a standalone function for reduced genericity. Co-authored-by: Josh Stone <cuviper@gmail.com>
2 parents 8d2e048 + dbc114f commit 83b67e2

28 files changed

+442
-241
lines changed

rayon-core/src/job.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@ where
109109
R: Send,
110110
{
111111
unsafe fn execute(this: *const Self) {
112+
fn call<R>(func: impl FnOnce(bool) -> R) -> impl FnOnce() -> R {
113+
move || func(true)
114+
}
115+
112116
let this = &*this;
113117
let abort = unwind::AbortIfPanic;
114118
let func = (*this.func.get()).take().unwrap();
115-
(*this.result.get()) = match unwind::halt_unwinding(|| func(true)) {
119+
(*this.result.get()) = match unwind::halt_unwinding(call(func)) {
116120
Ok(x) => JobResult::Ok(x),
117121
Err(x) => JobResult::Panic(x),
118122
};

rayon-core/src/join/mod.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ where
9898
RA: Send,
9999
RB: Send,
100100
{
101-
join_context(|_| oper_a(), |_| oper_b())
101+
#[inline]
102+
fn call<R>(f: impl FnOnce() -> R) -> impl FnOnce(FnContext) -> R {
103+
move |_| f()
104+
}
105+
106+
join_context(call(oper_a), call(oper_b))
102107
}
103108

104109
/// Identical to `join`, except that the closures have a parameter
@@ -115,22 +120,30 @@ where
115120
RA: Send,
116121
RB: Send,
117122
{
123+
#[inline]
124+
fn call_a<R>(f: impl FnOnce(FnContext) -> R, injected: bool) -> impl FnOnce() -> R {
125+
move || f(FnContext::new(injected))
126+
}
127+
128+
#[inline]
129+
fn call_b<R>(f: impl FnOnce(FnContext) -> R) -> impl FnOnce(bool) -> R {
130+
move |migrated| f(FnContext::new(migrated))
131+
}
132+
118133
registry::in_worker(|worker_thread, injected| unsafe {
119134
log!(Join {
120135
worker: worker_thread.index()
121136
});
122137

123-
let latch = SpinLatch::new();
124-
125138
// Create virtual wrapper for task b; this all has to be
126139
// done here so that the stack frame can keep it all live
127140
// long enough.
128-
let job_b = StackJob::new(|migrated| oper_b(FnContext::new(migrated)), latch);
141+
let job_b = StackJob::new(call_b(oper_b), SpinLatch::new());
129142
let job_b_ref = job_b.as_job_ref();
130143
worker_thread.push(job_b_ref);
131144

132145
// Execute task a; hopefully b gets stolen in the meantime.
133-
let status_a = unwind::halt_unwinding(move || oper_a(FnContext::new(injected)));
146+
let status_a = unwind::halt_unwinding(call_a(oper_a, injected));
134147
let result_a = match status_a {
135148
Ok(v) => v,
136149
Err(err) => join_recover_from_panic(worker_thread, &job_b.latch, err),

src/iter/collect/mod.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::{IndexedParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
2-
use std::collections::LinkedList;
32
use std::slice;
43
use std::sync::atomic::{AtomicUsize, Ordering};
54

@@ -138,24 +137,10 @@ where
138137
}
139138
None => {
140139
// This works like `extend`, but `Vec::append` is more efficient.
141-
let list: LinkedList<_> = par_iter
142-
.fold(Vec::new, |mut vec, elem| {
143-
vec.push(elem);
144-
vec
145-
})
146-
.map(|vec| {
147-
let mut list = LinkedList::new();
148-
list.push_back(vec);
149-
list
150-
})
151-
.reduce(LinkedList::new, |mut list1, mut list2| {
152-
list1.append(&mut list2);
153-
list1
154-
});
155-
156-
self.reserve(list.iter().map(Vec::len).sum());
157-
for mut vec in list {
158-
self.append(&mut vec);
140+
let list = super::extend::collect(par_iter);
141+
self.reserve(super::extend::len(&list));
142+
for ref mut vec in list {
143+
self.append(vec);
159144
}
160145
}
161146
}

src/iter/copied.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ where
102102
T: 'a + Copy,
103103
{
104104
type Item = T;
105-
type IntoIter = iter::Map<P::IntoIter, fn(&T) -> T>;
105+
type IntoIter = iter::Cloned<P::IntoIter>;
106106

107107
fn into_iter(self) -> Self::IntoIter {
108108
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
109-
self.base.into_iter().map(|&x| x)
109+
self.base.into_iter().cloned()
110110
}
111111

112112
fn min_len(&self) -> usize {
@@ -211,7 +211,7 @@ where
211211
I: IntoIterator<Item = &'a T>,
212212
{
213213
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
214-
self.base = self.base.consume_iter(iter.into_iter().map(|&x| x));
214+
self.base = self.base.consume_iter(iter.into_iter().cloned());
215215
self
216216
}
217217

0 commit comments

Comments
 (0)