Почему `String (описывающий: Class.self)` медленнее, чем `NSStringFromClass (Class.self)`? - PullRequest
2 голосов
/ 17 марта 2019

Рассмотрим следующую программу:

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

Первое измерение всегда самое дорогое (возможно, из-за ленивых действий во время выполнения), поэтому мы его пропустим.

Все остальные измерения показывают, что быстрота медленнее.

У меня также есть демонстрационный проект с тестом на получение строки из 1000 различных классов, который показывает:

  • Свифт String(describing: Class.self) работает медленнее, чем Objective-C NSClassFromString(Class.self) (30..150 мкс против 4..12 мкс)

  • Вызов String(describing: Class.self) Swift для разных классов становится все медленнее и медленнее с каждым новым классом, время Objective-C остается прежним

Есть идеи для такого поведения?

Ответы [ 2 ]

3 голосов
/ 17 марта 2019

возможно из-за ленивых действий во время выполнения

Внимание, первые обращения к чему-либо могут быть медленнее по разным причинам, включая разрешение динамически загружаемых библиотек.

Есть идеи для такого поведения?

Первое предположение: String(describing:) принимает любое значение , выясняет, какое это значение (в описании говорится, что он проверяет соответствие трем различным протоколам), а затем вызывает соответствующие функции. описать стоимость. Однако NSStringFromClass принимает только Class значения, которые проверяются во время компиляции, а затем напрямую вызывают функции времени выполнения, необходимые для получения имени класса в виде строки, без необходимости тестирования и перехода по типу передаваемого значения.

TLDR: больше работы занимает больше времени, тестирование и ветвление замедляют работу.

НТН

2 голосов
/ 17 марта 2019

Вы сравниваете яблоки с легковыми автомобилями.

  • NSStringFromClass выполняет очень специфическую работу, включающую только типы классов, и используется для преобразования, связанного с динамической природой Objective.-C программы.

  • String(describing:) в Swift превращает что угодно в строковое представление и предназначено (и подходит) только для отладки .Он не будет использоваться для любого пользовательского кода, и никакие значимые действия программы не будут зависеть от его вывода.Таким образом, он не появится в выпущенном приложении, и его скорость не учитывается.Поэтому ваш вопрос оптимизируется не только преждевременно, но и излишне;скорость String(describing:) не важна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...