大型结构体的Swift等同一致性:运算符函数'=='进行类型检查花费了xxx毫秒

ua4mk5z4  于 2023-03-28  发布在  Swift
关注(0)|答案(1)|浏览(101)

我在Swift中有一个很大的结构(通常是SwiftUI必须的),我需要在我的应用程序的多个地方使用Equatable(也是为了加速SwiftUI)。
当我打开编译器的-Xfrontend -warn-long-expression-type-checking=200标志时,相等运算符被突出显示,其中一些需要0.5s(!)来进行类型检查。
有没有一种方法可以重写检查,使类型检查更快?
这种检查的例子:

public static func == (lhs: ScrollableGraphicForecastView, rhs: ScrollableGraphicForecastView) -> Bool {
        return lhs.viewId == rhs.viewId
            && lhs.nowHash == rhs.nowHash
            && lhs.canScrollAndFitAll == rhs.canScrollAndFitAll
            && lhs.forecast == rhs.forecast
            && lhs.renderContent == rhs.renderContent
            && lhs.renderContext == rhs.renderContext
            && lhs.renderOptions == rhs.renderOptions
            && lhs.renderData == rhs.renderData
            && lhs.daysOutlookSource == rhs.daysOutlookSource
            && lhs.dataSettable == rhs.dataSettable
            && lhs.colorScheme == rhs.colorScheme
            && lhs.fineHorizontalSizeClass == rhs.fineHorizontalSizeClass
            && lhs.aspectRatio == rhs.aspectRatio
            && lhs.scrollStep == rhs.scrollStep
            && lhs.scrollStepCount == rhs.scrollStepCount
            /// State
            && lhs.scaleInProgress == rhs.scaleInProgress
            && lhs.scaleAnchor == rhs.scaleAnchor
            && lhs.scale == rhs.scale
            && lhs.scaleCoefficient == rhs.scaleCoefficient
            && lhs.lastScaleValue == rhs.lastScaleValue
            && lhs.visibleChartStartRelative == rhs.visibleChartStartRelative
            && lhs.absoluteScrollOffset == rhs.absoluteScrollOffset
            && lhs.containerSize == rhs.containerSize
            && lhs.chartSize == rhs.chartSize
            && lhs.midScreenAbsoluteScrollOffset == rhs.midScreenAbsoluteScrollOffset
            && lhs.stagger == rhs.stagger
    }

我找到的唯一相关信息是this thread-其要点是在每种情况下都有许多==运算符需要考虑,但我想说对于结构或标量类型,这应该不难,并且您可以单独比较每对比较...

gab6jxml

gab6jxml1#

主要的问题是它是一个庞大的表达式,这对编译器来说真的很难。我推荐的语法是if

if
    lhs.viewId == rhs.viewId,
    lhs.nowHash == rhs.nowHash,
    ...
    lhs.stagger == rhs.stagger
{
    return true
} else {
    return false
}

这将工作分解为许多小表达式,这些表达式更容易进行类型检查。
也就是说,我也会重新评估是什么阻止了你使用内置一致性。所有可见的属性都应该是Equatable的一部分,内置一致性将防止未来的错误,如果你添加属性,或剪切和粘贴错误,可能发生相同类型的属性。

相关问题