-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Modernize Set and Dictionary internals #18181
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
Conversation
@@ -390,7 +382,7 @@ extension Set: Collection { | |||
/// to the set. Don't expect any particular ordering of set elements. | |||
/// | |||
/// If the set is empty, the value of this property is `nil`. | |||
@inlinable // FIXME(sil-serialize-all) | |||
@inlinable | |||
public var first: Element? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this really does materially perform better than the default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default creates an iterator, which complicates the native case, but improves the bridged case -- _CocoaSet.startIndex
is currently O(n), while the iterator uses fast enumeration. 😦
Ideally this should dispatch to _variant
and do the right thing in each case. Or we could just remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it turns out this is the correct way to implement this, despite the performance hit.
Bridged indices are currently based on -[NSDictionary allKeys]
, which is not guaranteed to use the same element ordering as an enumerator. (Which indicates Dictionary/Set iterators may sometimes return elements in a different order than indices. 😭)
I think we should change indices to use enumerators, and soon.
4f2c2a1
to
4a7bb11
Compare
@swift-ci please test |
The benchmarks shouldn't be affected, although there were a couple changes to inlinability. |
Build failed |
Build failed |
Build comment file:Optimized (O)Regression (22)
Improvement (19)
No Changes (419)
Unoptimized (Onone)Regression (14)
Improvement (25)
No Changes (421)
Hardware Overview
|
@swift-ci please test |
@swift-ci test |
@swift-ci benchmark |
The |
Build failed |
Build failed |
Build comment file:Optimized (O)Regression (13)
Improvement (15)
No Changes (431)
Unoptimized (Onone)Regression (14)
Improvement (28)
No Changes (417)
Hardware Overview
|
The plot thickens! |
Please test with following PR: @swift-ci please test |
Build failed |
b89f2df
to
646e22d
Compare
Please test with the following PR: @swift-ci test |
Build failed |
2b44d08
to
a5caa28
Compare
Please test with the following PR: @swift-ci test |
@swift-ci please test and merge |
7461b7d
to
b98c0e4
Compare
- Rename variant enum types and move them into the corresponding struct: _VariantSetBuffer => Set._Variant _VariantDictionaryBuffer => Dictionary._Variant I found the buffer suffix did not positively contribute to understanding these types. And the extra indirection of the typealiases wasn't exactly helpful, either. - Remove internal typealiases that resolved to these.
This is primarily for documentation purposes, although the default implementation (based on an iterator) may not return the correct value for bridged dictionaries with exotic implementations.
A Dictionary.removeValue(forKey:) benchmark regressed 35% because recent changes in this PR caused an _UnsafeBitMap member to not be inlined in its implementation. (This was probably triggered by moving a method from Dictionary._Variant to _NativeDictionary.) Add @inline(__always) to _UnsafeBitMap members. While we’re at it, make _UnsafeBitMap @usableFromInline. It’s only public for testing purposes.
… property names This makes it easier to define lldb data formatters for these types.
DictionaryIterator & SetIterator have been renamed Dictionary.Iterator and Set.Iterator, with compatibility typealiases.
The startBucket argument is _bucket(key) in the vast majority of cases. Add an overload with this default value.
b98c0e4
to
fa0a96e
Compare
@swift-ci please test |
fa0a96e
to
ac92c02
Compare
So many typos... 🤦♂️ @swift-ci please test |
ac92c02
to
d1ec3b9
Compare
@swift-ci please test |
@swift-ci please smoke test compiler performance |
1 similar comment
@swift-ci please smoke test compiler performance |
Build comment file:Summary for master smoketestUnexpected test results, excluded stats for Kingfisher, ReactiveCocoa Regressions found (see below) Debugdebug briefRegressed (0)
Improved (0)
Unchanged (delta < 1.0% or delta < 100.0ms) (3)
debug detailedRegressed (1)
Improved (0)
Unchanged (delta < 1.0% or delta < 100.0ms) (22)
Releaserelease briefRegressed (0)
Improved (1)
Unchanged (delta < 1.0% or delta < 100.0ms) (2)
release detailedRegressed (1)
Improved (5)
Unchanged (delta < 1.0% or delta < 100.0ms) (17)
|
That first wall time regression was just noise, then, not a problem. |
Clean up Set and Dictionary internals to improve readability and to prepare for upcoming resiliency improvements.
Nest public iterator types under the corresponding collection type, with a compatibility typealias.
SetIterator<Element>
⟹Set<Element>.Iterator
DictionaryIterator<Key, Value>
⟹Dictionary<Key, Value>.Iterator
Nest auxiliary types under the corresponding higher-level type. Remove confusing
Buffer
suffix. Unify naming of enums representing native/cocoa variants._VariantSetBuffer<Element>
⟹Set<Element>._Variant
SetIndexRepresentation<Element>
⟹Set<Element>.Index._Variant
SetIteratorRepresentation<Element>
⟹Set<Element>.Iterator._Variant
_NativeSetBuffer<Element>
⟹_NativeSet<Element>
_NativeSetIndex<Element>
⟹_NativeSet<Element>.Index
_CocoaSetBuffer
⟹_CocoaSet
_CocoaSetIndex
⟹_CocoaSet.Index
_CocoaSetIterator
⟹_CocoaSet.Iterator
(Ditto for
Dictionary
.)Add explicit types representing native iterators:
_NativeSet<Element>.Iterator
and_NativeDictionary<Key, Value>.Iterator
. Previously these were exploded into associated values on the native case of the top-level iterator variant.Make Cocoa helper class names a little bit more helpful in Cocoa context.
_NativeSetNSEnumerator
⟹_SwiftSetNSEnumerator
_NativeDictionaryNSEnumerator
⟹_SwiftDictionaryNSEnumerator
Adjust internal property and variable names accordingly.
To enhance readability, remove internal typealiases wherever possible.
Audit inlinability.
rdar://problem/42585384