快速类型检查在很短的功能上花费的时间太长

问题描述 投票:17回答:1

我将Swift编译器标志-warn-long-function-bodies设置为90毫秒,以查看我的项目中哪些函数的编译时间太长(由于类型检查)。

我有以下方法:

func someKey(_ sectionType: SectionType, row: Int) -> String {
    let suffix = row == 0 ? "top" : "content"
    return "\(sectionType)_\(suffix)"
}

([SectionType是一个字符串支持的枚举)

如上所述,在2017年MacBook Pro上需要96ms。我尝试的第一件事是规避字符串插值,并使用\(sectionType.rawValue)而不是\(sectionType),但是现在它给了我[[106 ms。错误的动作...

接下来,我更改了:

let suffix = row == 0 ? "top" : "content"

至:

let suffix = "top"

警告消失了,因此是引起问题的三元运算符。 

我尝试这样做:

let suffix: String = { // Note the type annotation! if row == 0 { return "top" } return "content" }()

...但是现在是

closure耗时97毫秒(整个功能101)。

我什至尝试了更明确的方法:

let suffix: String = { if row == 0 { return String("top") } else { return String("content") } }()

...我得到关闭:94ms;功能:98ms。

发生了什么事?

我的90毫秒限制太低了吗?我知道存在(是?)带有[[dictionary文字的类型检查错误,但这似乎完全不同...?

我的环境是Xcode 8.3.2(8E2002),斯威夫特:Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)


但是等等!还有更多...

我尝试过此函数体:

func someKey(_ sectionType: SectionType, row: Int) -> String { if row == 0 { return "\(sectionType.rawValue)_top" } else { return "\(sectionType.rawValue)_content" } }

...需要97ms〜112ms!?


Addendum:
我将函数和枚举移植到一个干净的,最小的项目(单视图应用程序)中,该项目设置了相同的警告,但没有发生。我确定整个项目都会以某种方式影响这种方法,但是还不能确定如何...


附录2:我测试了我的函数的静态版本:不管row的值如何,都使用固定后缀“ top”(此过程少于90毫秒,并且不会触发警告),

但是添加了以下if块:

func someKey(_ sectionType: SectionType, row: Int) -> String { if row == 0 { print("zero") } else { print("non-zero") } let suffix: String = "top" return "\(sectionType)_\(suffix)" } 这使我回到96〜98毫秒!
因此将行与零进行比较时会出现问题?


解决方法:我一直在玩我的代码,并以某种方式发现如果我用if语句替换switch块,问题就消失了:

func someKey(_ sectionType: SectionType, row: Int) -> String { let suffix: String = { switch row { case 0: return "top" default: return "content" } }() return "\(sectionType)_\(suffix)" } ((我不会回答自己的问题,因为我不认为这是对实际情况的解释)

swift type-inference
1个回答
0
投票
我在Xcode 11中有类似的结果(〜93ms),但是使用以下命令,编译时间减少到〜23ms:

func someKey(_ sectionType: SectionType, row: Int) -> String { var suffix = "top" if row != 0 { suffix = "content" } return "\(sectionType)_\(suffix)" }

通过更改这条线上的逻辑,我认为我们可以证明它是三元逻辑,因为该方法可减少到〜1ms。我刚刚将row设为布尔值。

func someKey(_ sectionType: SectionType, row: Bool) -> String {
    let suffix = row ? "top" : "content"
    return "\(sectionType)_\(suffix)"
}

同样(无双关语),将三元逻辑更改为let suffix = row != 0 ? "top" : "content"可使编译时间减半。这与我的第一个代码块相当。对于Swift来说|===更快。

© www.soinside.com 2019 - 2024. All rights reserved.