当前位置: 首页 > 知识库问答 >
问题:

为什么“String(description:Class.self)”比“NSStringFromClass(Class.self)”慢?

高和通
2023-03-14

考虑以下程序:

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

第一个度量总是最昂贵的(可能是由于一些懒惰的运行时操作),因此我们将跳过它。

所有其他测量结果表明,swift速度较慢。

我还有一个演示项目,其中有一个从1000个不同的类中获取字符串的基准,该项目显示:

>

  • Swift的String(描述:Class.self)比Objective-C的NSClassFromString(Class.self)工作得慢(30...150μs vs 4...12μs)

    在不同的类上调用Swift的String(描述:Class.self)随着每个新类的出现变得越来越慢,而Objective-C时间保持不变

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

  • 共有2个答案

    闽阳州
    2023-03-14

    你在比较苹果和汽车。

    >

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

    Swift中的字符串(描述:)将任何内容转换为字符串表示,并且仅用于调试。它不会用于任何面向用户的代码,并且没有任何有意义的程序操作将取决于其输出。因此,它不会出现在发布的应用程序中,其速度也不重要。因此,你的问题不仅过早地优化了,而且是不必要的;字符串(描述:)的速度并不重要。

  • 艾浩广
    2023-03-14

    可能是由于一些懒惰的运行时操作

    事实上,由于各种原因,包括动态加载库的解析,对任何东西的第一次调用都可能较慢。

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

    第一个猜测是String(描述:)获取任何值,计算出它是什么样的值(它的描述说明它测试与三种不同协议的一致性),然后调用适当的函数来描述值。然而NSStringFromClass只获取Class值,在编译时检查,然后直接调用将类名作为字符串获取所需的运行时函数,而无需对传递的值类型进行测试和分支。

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

    HTH

     类似资料:
    • 问题内容: 给出以下代码: 为什么会这样?我以为布尔值会被强制转换为数字。因此变得和变。第二条if语句很有意义,但是我不明白为什么第一条语句导致要评估内部循环。这里发生了什么? 问题答案: 它被强制转换为布尔值。任何非空字符串的求值为true。 根据[ECMAScript语言规范]: ## 12.5 声明 ### 语义学 生产 IfStatement : Expression Statement

    • 问题内容: 他们在React文档中说: React还支持在任何组件上使用字符串(而不是回调)作为ref prop,尽管 这种方法目前在大多数情况下都是传统的 。 https://facebook.github.io/react/docs/more-about- refs.html 请看以下示例: 为什么我更喜欢这个,而不是: ? 第二个例子看起来更加干净和容易。 是否存在不建议使用string方法

    • 问题内容: 我的代码在以下一行中断了一个nullpointerexception: 在此语句之前,我声明stringVariable并将其设置为数据库字段。 在此声明中,我试图检测该字段是否具有值,但是不幸的是它损坏了! 有什么想法吗? 问题答案: 用 为了测试是否是。 该方法(以及所有其他方法)需要为不是。

    • 问题内容: 在 Java 7中 ,对象可以位于语句的表达式中。有人可以从官方文档中解释以下声明吗? 与使用链式if-then-else语句相比,Java编译器通常从使用 String对象的 switch语句生成更有效的字节码。 问题答案: Java代码 具有一个类的两个版本,例如 与: 与: 字节码 让我们看一下字节码。获取版本的字节码: 获取版本的字节码: 结论 在第一个版本中,通过为每个条件调

    • 我昨天对一个答案发表了评论,其中有人在正则表达式中使用了,而不是或。我说使用范围或数字说明符可能比使用字符集更快。 我决定今天测试一下,并惊讶地发现(至少在C#regex引擎中)似乎比其他两个似乎没有太大区别的任何一个都慢。这是我的测试输出超过10000个随机字符串,其中包含1000个随机字符,其中5077个实际上包含一个数字: 这对我来说是一个惊喜,有两个原因,如果有人能解释一下,我会很感兴趣: