Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use `fold` in `Iterator::last` default implementation #62481

Merged
merged 1 commit into from Jul 11, 2019

Conversation

@czipperz
Copy link
Contributor

commented Jul 7, 2019

We already use it in all the other methods. Consistency + potential perf is a pretty nice win!

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Jul 7, 2019

r? @sfackler

(rust_highfive has picked a reviewer for you, use r? to override)

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 7, 2019

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 7, 2019

So nth doesn't work because Self: Sized is not necessarily fulfilled. Why does try_fold require Self: Sized? The default implementation doesn't use it and it doesn't take self by value. Strange

@czipperz czipperz force-pushed the czipperz:iterator-last-nth-use-for_each branch from aa0c942 to 23450c3 Jul 7, 2019

@cuviper

This comment has been minimized.

Copy link
Member

commented Jul 8, 2019

Regarding try_fold -- methods with generic parameters need Self: Sized for trait object safety.

The last() change looks fine to me.

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 8, 2019

Mmh. I didn't think about that. I'll change the title.

@czipperz czipperz changed the title Use for_each and try_fold in Iterator::{last, nth} default implementations Use `for_each` in `Iterator::last` default implementation Jul 8, 2019

@scottmcm

This comment has been minimized.

Copy link
Member

commented Jul 8, 2019

Looks good; thanks for the PR!

@bors r+ rollup

@bors

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2019

📌 Commit 23450c3 has been approved by scottmcm

@scottmcm scottmcm assigned scottmcm and unassigned sfackler Jul 8, 2019

@scottmcm

This comment has been minimized.

Copy link
Member

commented Jul 8, 2019

@bors r-

Actually, @czipperz, can you squash the commits here please? (Or just force-push to
53ce67c.) Let's not merge in history that immediately reverts itself :)

@timvermeulen

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2019

It shouldn't matter, but you may as well use fold here?

@llogiq

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2019

I just did a quick benchmark and self.fold(None, move |_, x| Some(x)) was around 10% faster, besides being shorter and IMHO more readable.

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 9, 2019

I'm surprised it is that much faster wow! Could you share your benchmark code / data?

@llogiq

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2019

#![feature(test)]

extern crate test;
use test::{black_box, Bencher};

#[bench]
fn bench_for_each(b: &mut Bencher) {
    fn last<I: Iterator>(i: I) -> Option<<I as Iterator>::Item> where I: Sized {
        let mut last = None;
        i.for_each(|x| last = Some(x));
        last
    }
    let v = vec![0usize; 1024];
    b.iter(|| { last(black_box(v.iter())) })
}

#[bench]
fn bench_fold(b: &mut Bencher) {
    fn last<I: Iterator>(i: I) -> Option<<I as Iterator>::Item> where I: Sized {
        i.fold(None, move |_, x| Some(x))
    }
    let v = vec![0usize; 1024];
    b.iter(|| { last(black_box(v.iter())) })
}

Oops, I forgot running the benchmark with -C opt_level=3. The for_each version gets zero runtime with that, which kind of invalidates the benchmark, though. More research is needed.

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 9, 2019

I do think fold is clearer though

@czipperz czipperz changed the title Use `for_each` in `Iterator::last` default implementation Use `fold` in `Iterator::last` default implementation Jul 10, 2019

Use fold in Iterator::last
Replace last impl with fold

@czipperz czipperz force-pushed the czipperz:iterator-last-nth-use-for_each branch from 30e6ec3 to 76a8bc2 Jul 10, 2019

@czipperz

This comment has been minimized.

Copy link
Contributor Author

commented Jul 10, 2019

@scottmcm squashed it up

@scottmcm

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

Thanks, @czipperz!

@bors r+ rollup

@bors

This comment has been minimized.

Copy link
Contributor

commented Jul 10, 2019

📌 Commit 76a8bc2 has been approved by scottmcm

Centril added a commit to Centril/rust that referenced this pull request Jul 10, 2019

Rollup merge of rust-lang#62481 - czipperz:iterator-last-nth-use-for_…
…each, r=scottmcm

Use `fold` in `Iterator::last` default implementation

We already use it in all the other methods.  Consistency + potential perf is a pretty nice win!

bors added a commit that referenced this pull request Jul 10, 2019

Auto merge of #62561 - Centril:rollup-5pxj3bo, r=Centril
Rollup of 5 pull requests

Successful merges:

 - #62275 (rustc_mir: treat DropAndReplace as Drop + Assign in qualify_consts.)
 - #62465 (Sometimes generate storage statements for temporaries with type `!`)
 - #62481 (Use `fold` in `Iterator::last` default implementation)
 - #62493 (#62357: doc(ptr): add example for {read,write}_unaligned)
 - #62532 (Some more cleanups to syntax::print)

Failed merges:

r? @ghost

bors added a commit that referenced this pull request Jul 10, 2019

Auto merge of #62561 - Centril:rollup-5pxj3bo, r=Centril
Rollup of 5 pull requests

Successful merges:

 - #62275 (rustc_mir: treat DropAndReplace as Drop + Assign in qualify_consts.)
 - #62465 (Sometimes generate storage statements for temporaries with type `!`)
 - #62481 (Use `fold` in `Iterator::last` default implementation)
 - #62493 (#62357: doc(ptr): add example for {read,write}_unaligned)
 - #62532 (Some more cleanups to syntax::print)

Failed merges:

r? @ghost

@bors bors merged commit 76a8bc2 into rust-lang:master Jul 11, 2019

3 checks passed

pr Build #20190710.15 succeeded
Details
pr (Linux mingw-check) Linux mingw-check succeeded
Details
pr (Linux x86_64-gnu-llvm-6.0) Linux x86_64-gnu-llvm-6.0 succeeded
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.