我将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)"
}
((我不会回答自己的问题,因为我不认为这是对实际情况的解释)
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来说|=
比==
更快。