请考虑以下程序:
import Foundation
import QuartzCore
class C: NSObject {}
func benchmark() {
let swift1 = CACurrentMediaTime()
let swiftString = String(describing: C.self)
let swift2 = CACurrentMediaTime()
let objc1 = CACurrentMediaTime()
let objcString = NSStringFromClass(C.self)
let objc2 = CACurrentMediaTime()
let timeForSwiftString = swift2 - swift1
let timeForObjcString = objc2 - objc1
print("timeForSwiftString / timeForObjcString:", timeForSwiftString / timeForObjcString)
}
for _ in 0..<20 {
benchmark()
}
输出将类似于
timeForSwiftString / timeForObjcString: 21.023079257409023
timeForSwiftString / timeForObjcString: 1.8032004909527086
timeForSwiftString / timeForObjcString: 2.929076507541501
timeForSwiftString / timeForObjcString: 3.1707763580662034
timeForSwiftString / timeForObjcString: 2.884789101770234
timeForSwiftString / timeForObjcString: 3.167761588431754
timeForSwiftString / timeForObjcString: 3.0066055331053776
timeForSwiftString / timeForObjcString: 3.0707174733951255
timeForSwiftString / timeForObjcString: 3.213085166384659
timeForSwiftString / timeForObjcString: 2.830997374357457
timeForSwiftString / timeForObjcString: 3.24157236450268
timeForSwiftString / timeForObjcString: 3.0462955824531646
timeForSwiftString / timeForObjcString: 2.887874789238326
timeForSwiftString / timeForObjcString: 3.1071486398963732
timeForSwiftString / timeForObjcString: 2.995876045716979
timeForSwiftString / timeForObjcString: 3.073833893272912
timeForSwiftString / timeForObjcString: 2.965068621921414
timeForSwiftString / timeForObjcString: 3.0622197750334306
timeForSwiftString / timeForObjcString: 3.0484172031541656
timeForSwiftString / timeForObjcString: 1.9362930766842597
第一次测量始终是最昂贵的(可能是由于某些懒惰的运行时操作所致),因此我们将其跳过。
所有其他测量结果都表明,速度较慢。
我还有一个demo project,其基准是从1000个不同的类中获取字符串,该字符串显示:
Swift的String(describing: Class.self)
的运行速度比Objective-C的NSClassFromString(Class.self)
慢(30..150μs与4..12μs)
在每个新类上调用Swift的String(describing: Class.self)
会越来越慢,
而Objective-C时间保持不变
对这种行为有什么想法吗?
答案 0 :(得分:3)
可能是由于某些懒惰的运行时动作
请注意,由于各种原因(包括动态加载的库的解析),首次调用任何东西的速度都会变慢。
对这种行为有什么想法吗?
第一个猜测是String(describing:)
取任何值,弄清楚它是什么类型的值(描述中说明它测试是否符合三种不同的协议),然后调用适当的函数来描述值。但是NSStringFromClass
仅采用Class
值,该值在编译时检查,然后直接调用将类名作为字符串获取所需的运行时函数,而无需测试和分支该值的种类通过。
TLDR:更多的工作需要更多的时间,测试和分支会使您减速。
HTH
答案 1 :(得分:2)
您正在将苹果与汽车进行比较。
NSStringFromClass
做的是非常具体的工作,仅涉及类类型,并且用于与Objective-C程序的动态性质有关的转换。
String(describing:)
将任何内容转换为字符串表示形式,并且仅用于(且适用于)调试。它不会用于任何面向用户的代码,并且任何有意义的程序操作都不会取决于它的输出。因此,它不会出现在已发布的应用程序中,并且它的速度没有影响。因此,您的问题不仅过早而且不必要地优化。 String(describing:)
的速度并不重要。