代码之家  ›  专栏  ›  技术社区  ›  Tim

为什么使用`String(描述:自我类)`比`NSStringFromClass慢(自我类)`?

  •  0
  • Tim  · 技术社区  · 7 年前

    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个不同的类中获取字符串的基准测试显示:

    • String(describing: Class.self) NSClassFromString(Class.self)

    • 打电话给斯威夫特 在不同的班级里,每一个新的班级都会变得越来越慢, 而Objective-C时间保持不变

    对这种行为有什么想法吗?

    0 回复  |  直到 7 年前
        1
  •  2
  •   matt    7 年前

    • NSStringFromClass 执行高度特定的工作,仅涉及类类型,并用于与Objective-C程序的动态特性相关的转换。

    • String(describing:) 任何东西 它只适用于 调试 . 它不会用于任何面向用户的代码,也不会有任何有意义的程序操作依赖于它的输出。因此,它不会出现在发布的应用程序中,它的速度也不重要。因此,你的问题不仅过早而且不必要地优化了;速度 字符串(描述:) 不重要。

        2
  •  3
  •   CRD    7 年前

    可能是由于某些运行时延迟操作造成的

    在现场,对任何东西的第一次调用可能会因为各种原因而慢,包括动态加载库的解析。

    对这种行为有什么想法吗?

    第一个猜测是 String(describing:) 任何 值,计算出它是什么类型的值(它的描述说明它测试是否符合三种不同的协议),然后调用适当的函数来描述该值。然而 NSStringFromClass 只需要 Class

    TLDR:更多的工作需要更多的时间,测试和分支会减慢速度。