Skip to content

Commit 6d0b068

Browse files
committed
Focus as an iterator-like.
1 parent 64fdd5b commit 6d0b068

File tree

7 files changed

+782
-315
lines changed

7 files changed

+782
-315
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ Versioning](http://semver.org/spec/v2.0.0.html).
99
## [Unreleased]
1010

1111
### Added
12+
- `Vector` now has `Focus` and `FocusMut` APIs for caching index lookups,
13+
yielding huge performance gains when performing multiple adjacent index
14+
lookups. `Vector::iter` has been reimplemented using this API, and is now
15+
much simpler and about twice as fast as a result, and `Vector::iter_mut` now
16+
runs nearly an order of magnitude faster. Likewise, `Vector::sort` and
17+
`Vector::retain` are now using `FocusMut` and run considerably faster as a
18+
result.
1219
- `Vector::set` now returns the replaced value.
1320

1421
### Changed

benches/vector.rs

+129
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
55
#![feature(test)]
66

77
extern crate im;
8+
extern crate rand;
89
extern crate test;
910

11+
use im::iter::unfold_mut;
12+
use rand::distributions::{Distribution, Standard};
13+
use rand::Rng;
1014
use std::iter::FromIterator;
1115
use test::Bencher;
1216

1317
use im::vector::Vector;
1418

19+
fn rando<A>() -> impl Iterator<Item = A>
20+
where
21+
Standard: Distribution<A>,
22+
{
23+
let rng = rand::thread_rng();
24+
unfold_mut(rng, |rng| Some(rng.gen()))
25+
}
26+
1527
// fn vector_push_front(b: &mut Bencher, count: usize) {
1628
// b.iter(|| {
1729
// let mut l = Vector::new();
@@ -306,6 +318,123 @@ fn vector_append_100000(b: &mut Bencher) {
306318
vector_append(b, 100_000)
307319
}
308320

321+
fn vector_iter(b: &mut Bencher, count: usize) {
322+
let vec: Vector<i32> = rando().take(count).collect();
323+
b.iter(|| {
324+
let it = vec.iter();
325+
for _ in it {}
326+
})
327+
}
328+
329+
#[bench]
330+
fn vector_iter_10(b: &mut Bencher) {
331+
vector_iter(b, 10)
332+
}
333+
334+
#[bench]
335+
fn vector_iter_100(b: &mut Bencher) {
336+
vector_iter(b, 100)
337+
}
338+
339+
#[bench]
340+
fn vector_iter_1000(b: &mut Bencher) {
341+
vector_iter(b, 1000)
342+
}
343+
344+
#[bench]
345+
fn vector_iter_100000(b: &mut Bencher) {
346+
vector_iter(b, 100_000)
347+
}
348+
349+
fn vector_get_seq(b: &mut Bencher, count: usize) {
350+
let vec: Vector<i32> = rando().take(count).collect();
351+
b.iter(|| {
352+
for i in 0..count {
353+
let _ = vec.get(i);
354+
}
355+
})
356+
}
357+
358+
#[bench]
359+
fn vector_get_seq_10(b: &mut Bencher) {
360+
vector_get_seq(b, 10)
361+
}
362+
363+
#[bench]
364+
fn vector_get_seq_100(b: &mut Bencher) {
365+
vector_get_seq(b, 100)
366+
}
367+
368+
#[bench]
369+
fn vector_get_seq_1000(b: &mut Bencher) {
370+
vector_get_seq(b, 1000)
371+
}
372+
373+
#[bench]
374+
fn vector_get_seq_100000(b: &mut Bencher) {
375+
vector_get_seq(b, 100_000)
376+
}
377+
378+
fn vector_get_seq_focus(b: &mut Bencher, count: usize) {
379+
let vec: Vector<i32> = rando().take(count).collect();
380+
let mut focus = vec.focus();
381+
b.iter(|| {
382+
for i in 0..count {
383+
let _ = focus.get(i);
384+
}
385+
})
386+
}
387+
388+
#[bench]
389+
fn vector_get_seq_focus_10(b: &mut Bencher) {
390+
vector_get_seq_focus(b, 10)
391+
}
392+
393+
#[bench]
394+
fn vector_get_seq_focus_100(b: &mut Bencher) {
395+
vector_get_seq_focus(b, 100)
396+
}
397+
398+
#[bench]
399+
fn vector_get_seq_focus_1000(b: &mut Bencher) {
400+
vector_get_seq_focus(b, 1000)
401+
}
402+
403+
#[bench]
404+
fn vector_get_seq_focus_100000(b: &mut Bencher) {
405+
vector_get_seq_focus(b, 100_000)
406+
}
407+
408+
fn vector_get_seq_focus_mut(b: &mut Bencher, count: usize) {
409+
let mut vec: Vector<i32> = rando().take(count).collect();
410+
let mut focus = vec.focus_mut();
411+
b.iter(|| {
412+
for i in 0..count {
413+
let _ = focus.get(i);
414+
}
415+
})
416+
}
417+
418+
#[bench]
419+
fn vector_get_seq_focus_mut_10(b: &mut Bencher) {
420+
vector_get_seq_focus_mut(b, 10)
421+
}
422+
423+
#[bench]
424+
fn vector_get_seq_focus_mut_100(b: &mut Bencher) {
425+
vector_get_seq_focus_mut(b, 100)
426+
}
427+
428+
#[bench]
429+
fn vector_get_seq_focus_mut_1000(b: &mut Bencher) {
430+
vector_get_seq_focus_mut(b, 1000)
431+
}
432+
433+
#[bench]
434+
fn vector_get_seq_focus_mut_100000(b: &mut Bencher) {
435+
vector_get_seq_focus_mut(b, 100_000)
436+
}
437+
309438
// fn vector_extend(b: &mut Bencher, count: usize) {
310439
// let vec = Vec::from_iter(0..count);
311440
// b.iter(|| {

proptest-regressions/vector/mod.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Seeds for failure cases proptest has generated in the past. It is
2+
# automatically read and these particular cases re-run before any
3+
# novel cases are generated.
4+
#
5+
# It is recommended to check this file in to source control so that
6+
# everyone who runs the test benefits from these saved cases.
7+
xs 781088174 2402437932 46071810 3445483747 # shrinks to ref vec = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

0 commit comments

Comments
 (0)