1

假设我有这种功能和 DispatchQueue 逻辑。假设当synchLatest()被调用时它会触发"Code Block 1"两次。

应该怎么"Code Block 1"做?1.7 seconds5 seconds

let synchQueue = DispatchQueue(label: "com.dmapp.synchQueue", qos: .default, attributes: .concurrent)

let synchProcessQueue = DispatchQueue(label: "com.dmapp.processQueue", qos: .default, attributes: .concurrent)

func synchLatest() {
  while(someconditions) {
    synchQueue.async {
          ...
          let response = try grpcCall.receive()
          ...
          synchProcessQueue.async {
              ....
              measure("Code Block 1", {
                   if response.data.nickname != "" {
                        // Store in UserDefaults
                   }
              })
              ....
          }
    }
  }
}

@discardableResult
static func measure<A>(name: String = "", _ block: () -> A) -> A {
    let startTime = CACurrentMediaTime()
    let result = block()
    let timeElapsed = CACurrentMediaTime() - startTime
    print("Time: \(name) - \(timeElapsed)")
    return result
}

我是否以错误的方式在这里测量代码执行时间?

4

1 回答 1

1

CACurrentMediaTime是衡量时间的好方法。它的开销很低,并且不会遇到Dateor的问题CFAbsoluteTimeGetCurrent,即“不能保证结果单调递增”。</p>

基准测试时的一些一般准则包括:

  • 在开始基准测试之前让应用程序进入静止状态;
  • 不要同时运行相互独立的测试(因为它们可能会争夺相同的资源);
  • 重复多次;和
  • 更改执行基准测试的顺序以消除测量中的噪声。

如果您正在寻找手动使用的替代方法CACurrentMediaTime,另一种方法是使用路标和兴趣点,这不仅可以捕获所需的时间,还可以让您将仪器时间线过滤到相关时间段(并且您可能能够诊断出差异的来源)。

于 2019-08-19T16:35:26.843 回答