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 for IIterator<T> #3476

Merged
merged 2 commits into from
Feb 7, 2025
Merged

Optimize Iterator for IIterator<T> #3476

merged 2 commits into from
Feb 7, 2025

Conversation

kennykerr
Copy link
Collaborator

@kennykerr kennykerr commented Feb 6, 2025

C++/WinRT uses exceptions for error propagation and unfortunately exceptions continue to be very slow. I hadn't realized how much slower until a customer shared some logs. I decided to take a fresh look and compare the Rust implementation of IIterator<T>::Current returning E_BOUNDS to C++/WinRT's implementation that throws before returning E_BOUNDS. For a million calls:

  • Rust: 0.01s
  • C++/WinRT: 18.93s
  • C++/WinRT (without call to RoOriginate): 3.95s

So that's quite a difference. Ideally we can get C++/WinRT to avoid exceptions but this probably merits a tweak in Rust to avoid this pathological case as changing C++ is hard.

This change tweaks the Iterator trait implementation on the Rust side to use HasCurrent to avoid calls to Current and thus avoid those exceptions. With this change, the cost of iteration for C++ implementations approaches that of Rust.

Thanks to @JamesMcNellis for prodding me to look into this a bit more closely. He also gave a great talk on how exceptions work that you should definitely check out.

Comment on lines +464 to +468
let result = if self.HasCurrent().unwrap_or(false) {
self.Current().ok()
} else {
None
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the only change - the rest are the output of code generation used for validation.

@Ant4g0n1st
Copy link

Nice!

@kennykerr kennykerr merged commit 35c31ad into master Feb 7, 2025
78 checks passed
@kennykerr kennykerr deleted the HasCurrent branch February 7, 2025 02:56
@JamesMcNellis
Copy link
Collaborator

lgtm

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.

4 participants