apple / swift-collections

Commonly used data structures for Swift
Apache License 2.0
3.55k stars 270 forks source link

[OrderedDictionary] forward ordered dictionary values equality to values property #335

Closed vanvoorden closed 5 months ago

vanvoorden commented 5 months ago

Background

https://github.com/apple/swift-collections/issues/334

The current implementation of OrderedDictionary.Values.== forwards to Sequence.elementsEqual, which needs to perform a linear-time (O[N]) comparison over both collections.[1]

Since the "backing store" of our OrderedDictionary.Values is a ContiguousArray, we can forward that equality check through to ContiguousArray. If both Values instances point to the same identity, the ContiguousArray implementation will return early from the comparison.[2]

We perform a similar check (against the ContiguousArray) in our implementation of OrderedDictionary.==.[3]

[1] https://github.com/apple/swift/blob/main/stdlib/public/core/SequenceAlgorithms.swift#L319-L336 [2] https://github.com/apple/swift/blob/main/stdlib/public/core/ContiguousArray.swift#L1318-L1321 [3] https://github.com/apple/swift-collections/blob/main/Sources/OrderedCollections/OrderedDictionary/OrderedDictionary%2BEquatable.swift#L20-L22


Changes

We migrate from:

public static func ==(left: Self, right: Self) -> Bool {
  left.elementsEqual(right)
}

We migrate to:

public static func ==(left: Self, right: Self) -> Bool {
  left._base._values == right._base._values
}

Test Plan

Two new tests are added:


Checklist

vanvoorden commented 5 months ago

@swift-ci test

vanvoorden commented 5 months ago

@ingoem thanks for suggesting the reference equality check!

lorentey commented 5 months ago

@vanvoorden Can you please rebase this PR on top of the release/1.0 branch, rather than main?

I think it would make sense to ship this in the next patch release, rather than having it linger on main indefinitely.

vanvoorden commented 5 months ago

I think it would make sense to ship this in the next patch release, rather than having it linger on main indefinitely.

@lorentey Sounds good. Thanks!

vanvoorden commented 5 months ago

@lorentey Is there a CI job that can run Benchmarks on a diff to detect for regressions or improvements against base?

vanvoorden commented 5 months ago
2023-12-11-1 2023-12-11-2

Here are benchmarks running locally. The reason that OrderedDictionary.== is scaling linearly is because we are waiting on https://github.com/apple/swift-collections/pull/340. Optimizing the OrderedSet equality will optimize this one.

vanvoorden commented 5 months ago

@lorentey Thanks for reviewing!

lorentey commented 5 months ago

@swift-ci test

lorentey commented 5 months ago

(AFAIK, CI runs are still expected to fail on macOS. This is "fine", and it won't block us from landing this.)