Solve performance of values iterators #23
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR solves all iterator performance issues by ensuring that the used iterator implementation that is produced by types such as
Set
andMap
all directly relate to an iterator adapter provided bycore::iter
(i.e.std::iter
).After some investigation it was discovered that the difference in performance was due to different code generation, in particular when using an appropriately sized array directly it will be unrolled by rustc and LLVM https://godbolt.org/z/aW1fqa4xM.
This is very likely due to the internal use of
TrustedLen
, which is an unsafe trait the the compiler can use to determine the exact length of an iterator https://doc.rust-lang.org/src/core/iter/adapters/flatten.rs.html#118.So by using internal iterators even though it leads to more complex typing (somewhat mitigated through aliases) we're able to convince rustc to peel of all abstractions and as appropriate make use of loop unrolling. This means that for example the
Map::values
iterator should behave exactly like an[Option<T>; SIZE]
iterator for non-composite keys.