Hey all, I have a question about the performance impact of highly overloaded functions; == specifically. Specifically, about the potential impact of reducing the number of overloads in a build using the Swift 6.3 compiler, and whether any optimizations of this nature will remain effective after adopting Swift 6.4.
I think most folks reading this will already know that == is highly overloaded in any Swift codebase. My codebase has over 17,000 in total, on top of the numerous overloads in the Swift Standard Library and Apple libraries like Foundation, SwiftUI, etc. A representative file one of my coworkers checked listed 500 potential candidates to type check the statement _ = (==).
Inevitably, build times have gone up and uses of == have become a target for reducing build times; specifically, the implementations of == for our network models. We've found that switching from a series of lhs.a == rhs.a && lhs.b == rhs.b expressions to a series of individual guards using != can reduce build times, presumably because there are far less != implementations than == in the Swift stdlib, and because the large expressions have been broken down.
These functions take over 200ms to type-check, which might make it worth the cost in writing un-idiomatic Swift, though this is something that I personally would like to avoid. I'd also like to avoid solutions that replace == with some different symbol, like a unicode == doppelganger, though obviously that option is very much on the table.
So, the subject of my question: what if we don't implement "normal" Equatable at all? We'd find and replace all our impls of Equtable with a new protocol that uses a common == implementation:
public protocol MyEquatable: Equatable {
static func isEqual(lhs: Self, rhs: Self) -> Bool
}
extension MyEquatable {
public static func ==(lhs: Self, rhs: Self) -> Bool {
isEqual(
lhs: lhs,
rhs: rhs
)
}
}
That said, we don't have a good enough intuition for the impact of removing == impls to understand the impact of this; even if we reduce the number of == candidates visible in a given file, we might only be halving that number at best with this approach. We might try to benchmark this approach regardless, but I thought I'd ask here to see if anyone has any insights into the algorithmic complexities at work in type checking == uses.