swift 如何度量异步方法的性能?

t30tvxxf  于 2023-02-11  发布在  Swift
关注(0)|答案(1)|浏览(91)

我写了一个方法loadCountries(),它在调用时执行异步文件加载,然后通知它的输出工作完成。我试图在测试中测量这个方法的性能,但是我不知道如何在没有回调的情况下处理异步操作。
我发现有startMeasuring()stopMeasuring()方法允许手动设置测试的入口和终点,我尝试在输出模拟中调用后者:

let output = InteractorOutputMock()
output.onDisplay = { _ in
    self.stopMeasuring()
}

let interactor = PremiumLocationsChooserInteractor()
interactor.output = output

measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
    self.startMeasuring()
    interactor.loadCountries()
}

但是代码仍然在0秒内完成。我应该如何处理这个问题?
更新:
我也尝试过使用expectation,但是遇到了问题。我既不能在measure块内部调用它,也不能在measure块外部调用它。前者看起来如下所示,并导致代码在measure的第一次迭代中等待:

let outputCalledExpectation = XCTestExpectation(description: "Output   hasn't been called")
outputCalledExpectation.expectedFulfillmentCount = 10 // need to fullfill it 10 times since this is how much measure block is called
let output = InteractorOutputMock()
output.onDisplay = { _ in
    self.stopMeasuring() // called only once
    outputCalledExpectation.fulfill()
}

let interactor = PremiumLocationsChooserInteractor()
interactor.output = output

measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
    startMeasuring()
    interactor.loadCountries()
    wait(for: [outputCalledExpectation], timeout: 5.0) // then stack here
}

如果我尝试将wait方法移出块,就会得到异常-stopMeasuring is only supported from a block passed to -measure...Block:

measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
    startMeasuring()
    interactor.loadCountries()
}
wait(for: [outputCalledExpectation], timeout: 5.0) // get exception here
yyyllmsg

yyyllmsg1#

我用这个扩展来测量,对我来说就像一个魅力。

extension XCTestCase {
  func measureAsync(
    timeout: TimeInterval = 2.0,
    for block: @escaping () async throws -> Void,
    file: StaticString = #file,
    line: UInt = #line
  ) {
    measureMetrics(
      [.wallClockTime],
      automaticallyStartMeasuring: true
    ) {
      let expectation = expectation(description: "finished")
      Task { @MainActor in
        do {
          try await block()
          expectation.fulfill()
        } catch {
          XCTFail(error.localizedDescription, file: file, line: line)
          expectation.fulfill()
        }
      }
      wait(for: [expectation], timeout: timeout)
    }
  }
}

相关问题