如何在Swift中的DispatchQueue并发异步中测量代码块的执行时间?

时间:2019-07-12 09:00:43

标签: swift grand-central-dispatch grpc dispatch-queue

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

怎么可能是,在循环期间,执行"Code Block 1"只是从grpc响应中检索一个字符串,而在UserDefaults中存储了一个1.7 seconds,第二个是在循环中执行需要花费5 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
}

我在这里用错误的方式测量代码执行时间吗?

1 个答案:

答案 0 :(得分:1)

CACurrentMediaTime是衡量时间的一种好方法。它的开销很低,并且不会遇到Datedescriptor.__set_name__() method这样的问题,即“不能保证结果单调递增。”

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

  • 在开始基准测试之前让应用达到静止状态; <​​/ li>
  • 请勿同时进行相互独立的测试(因为它们可能会争用相同的资源);
  • 重复多次;和
  • 更改基准测试的顺序,以消除测量中的噪声。

如果您正在寻找手动使用CACurrentMediaTime的替代方法,另一种方法是使用CFAbsoluteTimeGetCurrent,它不仅可以捕获花费的时间,还可以过滤您的时间吗?仪器时间表到相关的时间段(您也许可以诊断出差异的来源)。