【问题标题】:How to measure code block execution time inside DispatchQueue concurrent async in Swift?如何在 Swift 中测量 DispatchQueue 并发异步中的代码块执行时间?
【发布时间】:2019-07-12 09:00:43
【问题描述】:

假设我有这种功能和 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
}

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

【问题讨论】:

  • 看起来你只是在对用户默认值的更新进行基准测试,我不知道为什么会这么慢。话虽如此,您正在对似乎同时运行的任务进行基准测试,所以如果有任何同步正在进行,我预计后者会更慢。
  • 谢谢你,这对我的分析也很有意义

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


【解决方案1】:

CACurrentMediaTime 是衡量时间的好方法。它的开销很低,不会遇到DateCFAbsoluteTimeGetCurrent 的“不保证结果单调递增”的问题。

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

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

如果您正在寻找手动使用 CACurrentMediaTime 的替代方法,另一种方法是使用 signposts and points of interest,它不仅可以记录所需的时间,而且您可以让您将仪器时间线过滤到相关的时间段(并且您可能能够诊断出差异的来源)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多