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

Optimize iterator adapters. #25035

Merged
merged 1 commit into from
May 6, 2015
Merged

Optimize iterator adapters. #25035

merged 1 commit into from
May 6, 2015

Conversation

Stebalien
Copy link
Contributor

Specifically, make count, nth, and last call the corresponding methods on the underlying iterator where possible. This way, if the underlying iterator has an optimized count, nth, or last implementations (e.g. slice::Iter), these methods will propagate these optimizations.

Additionally, change Skip::next to take advantage of a potentially optimized nth method on the underlying iterator.

This covers:

  • core::iter::Chain: count, last, nth
  • core::iter::Enumerate: count, nth
  • core::iter::Peekable: count, last, nth
  • core::iter::Skip: count, last, next (should call nth), nth
  • core::iter::Take: nth
  • core::iter::Fuse: count, last, nth

of #24214.

@rust-highfive
Copy link
Collaborator

r? @brson

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

@Stebalien
Copy link
Contributor Author

r? @aturon

@rust-highfive rust-highfive assigned aturon and unassigned brson May 1, 2015
@Gankra
Copy link
Contributor

Gankra commented May 1, 2015

Out of curiousity, do you have any numbers/examples of perf improvements from this change?

@Gankra
Copy link
Contributor

Gankra commented May 1, 2015

Ah I see. This is just part of a bigger "do it because we can" issue. In the past we pushed back on this kind of thing (in the hopes of some kind of legit specialization based on things like ExactSizeIterator). Didn't realize we'd changed direction on that.

} else if n == 0 {
self.next()
} else {
self.next();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be more clear as:

let old_n = self.n;
self.n = 0;
self.iter.nth(old_n + n)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Which would also allow merging with the previous branch)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point (although I'm going to do two nth calls to avoid the overflow issue).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I got rid of that branch but had to add another (I forgot to check if next returned None).

@aturon
Copy link
Member

aturon commented May 1, 2015

This is neat stuff! I left a few comments/questions, but the biggest thing I'd like to see is an expansion of the unit tests in libcoretest/iter.rs to get decent coverage of this code. In particular, since we haven't been specializing in the past, not very many combinations of adapters + methods are being tested.

@Stebalien
Copy link
Contributor Author

No. I don't really know the right way to benchmark this. Because these methods are asymptotically better, I can write benchmarks that give infinite speedups...

@Gankra
Copy link
Contributor

Gankra commented May 1, 2015

@Stebalien Ah good point. I suppose I was wondering if this allowed certain adaptors to be inline'd and optimized to "the right thing" that previously weren't. But yeah should be a uniform improvement.

@Stebalien
Copy link
Contributor Author

Addressed comments. TODO: Test.

@Stebalien
Copy link
Contributor Author

I realized I missed the by_ref iterator (impl<I: Iterator> Iterator for &mut I). Would you prefer it if I put that in a separate pull request?

@Stebalien
Copy link
Contributor Author

Added test cases.

@Stebalien
Copy link
Contributor Author

@aturon, Would you like me to squash?

@aturon
Copy link
Member

aturon commented May 5, 2015

@Stebalien Tests look great -- go ahead and squash, and then I'll send to bors. Thanks again for your work on this!

Specifically, make count, nth, and last call the corresponding methods
on the underlying iterator where possible. This way, if the underlying
iterator has an optimized count, nth, or last implementations (e.g.
slice::Iter), these methods will propagate these optimizations.

Additionally, change Skip::next to take advantage of a potentially
optimized nth method on the underlying iterator.
@Stebalien
Copy link
Contributor Author

Done (I think).

@aturon
Copy link
Member

aturon commented May 5, 2015

@bors: r+

@bors
Copy link
Contributor

bors commented May 5, 2015

📌 Commit 3fcbc31 has been approved by aturon

@bors
Copy link
Contributor

bors commented May 6, 2015

⌛ Testing commit 3fcbc31 with merge 6afa669...

bors added a commit that referenced this pull request May 6, 2015
Specifically, make count, nth, and last call the corresponding methods on the underlying iterator where possible. This way, if the underlying iterator has an optimized count, nth, or last implementations (e.g. slice::Iter), these methods will propagate these optimizations.

Additionally, change Skip::next to take advantage of a potentially optimized nth method on the underlying iterator.

This covers:

* core::iter::Chain: count, last, nth
* core::iter::Enumerate: count, nth
* core::iter::Peekable: count, last, nth
* core::iter::Skip: count, last, next (should call nth), nth
* core::iter::Take: nth
* core::iter::Fuse: count, last, nth

of #24214.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants