Skip to content

Commit 000abd3

Browse files
committed
Merge branch 'master' into binary-heap-ta
2 parents 148f0b5 + 245e943 commit 000abd3

File tree

810 files changed

+56113
-29701
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

810 files changed

+56113
-29701
lines changed

alloc/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ core = { path = "../core" }
1313
compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
1414

1515
[dev-dependencies]
16-
rand = "0.7"
17-
rand_xorshift = "0.2"
16+
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
17+
rand_xorshift = "0.3.0"
1818

1919
[[test]]
2020
name = "collectionstests"

alloc/benches/btree/map.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::collections::BTreeMap;
2-
use std::iter::Iterator;
32
use std::ops::RangeBounds;
43
use std::vec::Vec;
54

alloc/benches/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
// See https://github.com/rust-lang/rust/issues/73535#event-3477699747
33
#![cfg(not(target_os = "android"))]
44
#![feature(btree_drain_filter)]
5-
#![feature(map_first_last)]
5+
#![feature(iter_next_chunk)]
66
#![feature(repr_simd)]
77
#![feature(slice_partition_dedup)]
8+
#![feature(strict_provenance)]
89
#![feature(test)]
10+
#![deny(fuzzy_provenance_casts)]
911

1012
extern crate test;
1113

alloc/benches/slice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{mem, ptr};
22

3-
use rand::distributions::{Alphanumeric, Standard};
3+
use rand::distributions::{Alphanumeric, DistString, Standard};
44
use rand::Rng;
55
use test::{black_box, Bencher};
66

@@ -218,7 +218,7 @@ fn gen_strings(len: usize) -> Vec<String> {
218218
let mut v = vec![];
219219
for _ in 0..len {
220220
let n = rng.gen::<usize>() % 20 + 1;
221-
v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect());
221+
v.push(Alphanumeric.sample_string(&mut rng, n));
222222
}
223223
v
224224
}

alloc/benches/str.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::iter::Iterator;
12
use test::{black_box, Bencher};
23

34
#[bench]
@@ -122,14 +123,13 @@ fn bench_contains_short_short(b: &mut Bencher) {
122123
let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
123124
let needle = "sit";
124125

126+
b.bytes = haystack.len() as u64;
125127
b.iter(|| {
126-
assert!(haystack.contains(needle));
128+
assert!(black_box(haystack).contains(black_box(needle)));
127129
})
128130
}
129131

130-
#[bench]
131-
fn bench_contains_short_long(b: &mut Bencher) {
132-
let haystack = "\
132+
static LONG_HAYSTACK: &str = "\
133133
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
134134
ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
135135
eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
@@ -164,10 +164,48 @@ feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, i
164164
vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
165165
leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
166166
malesuada sollicitudin quam eu fermentum.";
167+
168+
#[bench]
169+
fn bench_contains_2b_repeated_long(b: &mut Bencher) {
170+
let haystack = LONG_HAYSTACK;
171+
let needle = "::";
172+
173+
b.bytes = haystack.len() as u64;
174+
b.iter(|| {
175+
assert!(!black_box(haystack).contains(black_box(needle)));
176+
})
177+
}
178+
179+
#[bench]
180+
fn bench_contains_short_long(b: &mut Bencher) {
181+
let haystack = LONG_HAYSTACK;
167182
let needle = "english";
168183

184+
b.bytes = haystack.len() as u64;
185+
b.iter(|| {
186+
assert!(!black_box(haystack).contains(black_box(needle)));
187+
})
188+
}
189+
190+
#[bench]
191+
fn bench_contains_16b_in_long(b: &mut Bencher) {
192+
let haystack = LONG_HAYSTACK;
193+
let needle = "english language";
194+
195+
b.bytes = haystack.len() as u64;
196+
b.iter(|| {
197+
assert!(!black_box(haystack).contains(black_box(needle)));
198+
})
199+
}
200+
201+
#[bench]
202+
fn bench_contains_32b_in_long(b: &mut Bencher) {
203+
let haystack = LONG_HAYSTACK;
204+
let needle = "the english language sample text";
205+
206+
b.bytes = haystack.len() as u64;
169207
b.iter(|| {
170-
assert!(!haystack.contains(needle));
208+
assert!(!black_box(haystack).contains(black_box(needle)));
171209
})
172210
}
173211

@@ -176,8 +214,20 @@ fn bench_contains_bad_naive(b: &mut Bencher) {
176214
let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
177215
let needle = "aaaaaaaab";
178216

217+
b.bytes = haystack.len() as u64;
218+
b.iter(|| {
219+
assert!(!black_box(haystack).contains(black_box(needle)));
220+
})
221+
}
222+
223+
#[bench]
224+
fn bench_contains_bad_simd(b: &mut Bencher) {
225+
let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
226+
let needle = "aaabaaaa";
227+
228+
b.bytes = haystack.len() as u64;
179229
b.iter(|| {
180-
assert!(!haystack.contains(needle));
230+
assert!(!black_box(haystack).contains(black_box(needle)));
181231
})
182232
}
183233

@@ -186,8 +236,9 @@ fn bench_contains_equal(b: &mut Bencher) {
186236
let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
187237
let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
188238

239+
b.bytes = haystack.len() as u64;
189240
b.iter(|| {
190-
assert!(haystack.contains(needle));
241+
assert!(black_box(haystack).contains(black_box(needle)));
191242
})
192243
}
193244

alloc/benches/vec.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rand::RngCore;
2-
use std::iter::{repeat, FromIterator};
2+
use std::iter::repeat;
33
use test::{black_box, Bencher};
44

55
#[bench]
@@ -762,3 +762,23 @@ fn bench_retain_whole_100000(b: &mut Bencher) {
762762
let mut v = black_box(vec![826u32; 100000]);
763763
b.iter(|| v.retain(|x| *x == 826u32));
764764
}
765+
766+
#[bench]
767+
fn bench_next_chunk(b: &mut Bencher) {
768+
let v = vec![13u8; 2048];
769+
770+
b.iter(|| {
771+
const CHUNK: usize = 8;
772+
773+
let mut sum = [0u32; CHUNK];
774+
let mut iter = black_box(v.clone()).into_iter();
775+
776+
while let Ok(chunk) = iter.next_chunk::<CHUNK>() {
777+
for i in 0..CHUNK {
778+
sum[i] += chunk[i] as u32;
779+
}
780+
}
781+
782+
sum
783+
})
784+
}

alloc/benches/vec_deque.rs

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::collections::VecDeque;
1+
use core::iter::Iterator;
2+
use std::{
3+
collections::{vec_deque, VecDeque},
4+
mem,
5+
};
26
use test::{black_box, Bencher};
37

48
#[bench]
@@ -53,6 +57,146 @@ fn bench_try_fold(b: &mut Bencher) {
5357
b.iter(|| black_box(ring.iter().try_fold(0, |a, b| Some(a + b))))
5458
}
5559

60+
/// does the memory bookkeeping to reuse the buffer of the Vec between iterations.
61+
/// `setup` must not modify its argument's length or capacity. `g` must not move out of its argument.
62+
fn into_iter_helper<
63+
T: Copy,
64+
F: FnOnce(&mut VecDeque<T>),
65+
G: FnOnce(&mut vec_deque::IntoIter<T>),
66+
>(
67+
v: &mut Vec<T>,
68+
setup: F,
69+
g: G,
70+
) {
71+
let ptr = v.as_mut_ptr();
72+
let len = v.len();
73+
// ensure that the vec is full, to make sure that any wrapping from the deque doesn't
74+
// access uninitialized memory.
75+
assert_eq!(v.len(), v.capacity());
76+
77+
let mut deque = VecDeque::from(mem::take(v));
78+
setup(&mut deque);
79+
80+
let mut it = deque.into_iter();
81+
g(&mut it);
82+
83+
mem::forget(it);
84+
85+
// SAFETY: the provided functions are not allowed to modify the allocation, so the buffer is still alive.
86+
// len and capacity are accurate due to the above assertion.
87+
// All the elements in the buffer are still valid, because of `T: Copy` which implies `T: !Drop`.
88+
mem::forget(mem::replace(v, unsafe { Vec::from_raw_parts(ptr, len, len) }));
89+
}
90+
91+
#[bench]
92+
fn bench_into_iter(b: &mut Bencher) {
93+
let len = 1024;
94+
// we reuse this allocation for every run
95+
let mut vec: Vec<usize> = (0..len).collect();
96+
vec.shrink_to_fit();
97+
98+
b.iter(|| {
99+
let mut sum = 0;
100+
into_iter_helper(
101+
&mut vec,
102+
|_| {},
103+
|it| {
104+
for i in it {
105+
sum += i;
106+
}
107+
},
108+
);
109+
black_box(sum);
110+
111+
let mut sum = 0;
112+
// rotating a full deque doesn't move any memory.
113+
into_iter_helper(
114+
&mut vec,
115+
|d| d.rotate_left(len / 2),
116+
|it| {
117+
for i in it {
118+
sum += i;
119+
}
120+
},
121+
);
122+
black_box(sum);
123+
});
124+
}
125+
126+
#[bench]
127+
fn bench_into_iter_fold(b: &mut Bencher) {
128+
let len = 1024;
129+
130+
// because `fold` takes ownership of the iterator,
131+
// we can't prevent it from dropping the memory,
132+
// so we have to bite the bullet and reallocate
133+
// for every iteration.
134+
b.iter(|| {
135+
let deque: VecDeque<usize> = (0..len).collect();
136+
assert_eq!(deque.len(), deque.capacity());
137+
let sum = deque.into_iter().fold(0, |a, b| a + b);
138+
black_box(sum);
139+
140+
// rotating a full deque doesn't move any memory.
141+
let mut deque: VecDeque<usize> = (0..len).collect();
142+
assert_eq!(deque.len(), deque.capacity());
143+
deque.rotate_left(len / 2);
144+
let sum = deque.into_iter().fold(0, |a, b| a + b);
145+
black_box(sum);
146+
});
147+
}
148+
149+
#[bench]
150+
fn bench_into_iter_try_fold(b: &mut Bencher) {
151+
let len = 1024;
152+
// we reuse this allocation for every run
153+
let mut vec: Vec<usize> = (0..len).collect();
154+
vec.shrink_to_fit();
155+
156+
// Iterator::any uses Iterator::try_fold under the hood
157+
b.iter(|| {
158+
let mut b = false;
159+
into_iter_helper(&mut vec, |_| {}, |it| b = it.any(|i| i == len - 1));
160+
black_box(b);
161+
162+
into_iter_helper(&mut vec, |d| d.rotate_left(len / 2), |it| b = it.any(|i| i == len - 1));
163+
black_box(b);
164+
});
165+
}
166+
167+
#[bench]
168+
fn bench_into_iter_next_chunk(b: &mut Bencher) {
169+
let len = 1024;
170+
// we reuse this allocation for every run
171+
let mut vec: Vec<usize> = (0..len).collect();
172+
vec.shrink_to_fit();
173+
174+
b.iter(|| {
175+
let mut buf = [0; 64];
176+
into_iter_helper(
177+
&mut vec,
178+
|_| {},
179+
|it| {
180+
while let Ok(a) = it.next_chunk() {
181+
buf = a;
182+
}
183+
},
184+
);
185+
black_box(buf);
186+
187+
into_iter_helper(
188+
&mut vec,
189+
|d| d.rotate_left(len / 2),
190+
|it| {
191+
while let Ok(a) = it.next_chunk() {
192+
buf = a;
193+
}
194+
},
195+
);
196+
black_box(buf);
197+
});
198+
}
199+
56200
#[bench]
57201
fn bench_from_array_1000(b: &mut Bencher) {
58202
const N: usize = 1000;

0 commit comments

Comments
 (0)