为什么UIFont(描述符:大小:)比UIFont(名称:大小:)慢x200?

时间:2016-01-22 20:00:33

标签: ios iphone

最近我注意到卷轴的性能正在放缓。我找到了问题,我发现原因是使用UIFont(descriptor:size:)构造函数创建的字体。我改变了UIFont(name:size:)的构造函数,我的问题得到了解决。

我在project中隔离了问题。代码是:

import UIKit

class ViewController: UIViewController {
  @IBOutlet weak var firstLabel: UILabel!
  @IBOutlet weak var secondLabel: UILabel!

  @IBAction func onStartTest(sender: AnyObject) {
    startMeasurement()
    let firstFont = UIFont(name: "Marker Felt", size: 16)
    firstLabel.font = firstFont
    finishMeasurement("UIFont(name)")

    startMeasurement()
    let secondFontDescriptor = UIFontDescriptor(name: "Marker Felt", size: 16)
    let secondFont = UIFont(descriptor: secondFontDescriptor, size: 16)
    secondLabel.font = secondFont
    finishMeasurement("UIFont(descriptor)")
  }
}

private var time: UInt64 = 0

public func startMeasurement() {
  time = mach_absolute_time()
}

public func finishMeasurement(name: String) {
  let duration = mach_absolute_time() - time
  print("* \(name) \(duration)ns")
}

这些是我的一些衡量标准:

iPhone 4S - iOS 9.0.2

* UIFont(name) 111,300ns
* UIFont(descriptor) 112,420,263ns

iPhone 6S - iOS iOS 9.2

* UIFont(name) 134,247ns
* UIFont(descriptor) 17,047,707ns

Simulator - iOS 9.2

* UIFont(name) 1,971,106ns
* UIFont(descriptor) 485,208,205ns

Simulator - iOS 8.1

* UIFont(name) 9,946,584ns
* UIFont(descriptor) 1,957,802,431ns

我做错了吗?

1 个答案:

答案 0 :(得分:5)

我在2018年的WWDC问了一位工程师,他基本上告诉了我这个:

描述符非常昂贵,因为它们每次都在搜索ENTIRE系统字体库以获得您提供的特性。他告诉我,这个搜索确实没有优化,所以永远不应该在滚动的情况下使用,应该只调用一次然后缓存。它是这样做的,因为你实际上并不需要指定字体名称,而只是指定它的各种特性,系统会为你提供一些东西。

然而,

UIFont(name: size:)非常快,因为它直接转到系统中请求的字体。它知道字体的位置,因为您已经给出了完整的确切名称,然后它可以缩放它。没有其他不错的功能。

它大致是O(n)操作与O(1)