Swift OperationQueue 开始下一个操作的时间
Swift OperationQueue time to start next operation
我有一组异步操作且相互依赖的任务。现在所有这些都是用自定义代码管理的,我想改用 OperationQueue。然而,时序性能非常关键。
在当前的实现中,当一个任务完成时,它会立即调用所需的代码来启动下一个任务。所以所涉及的时间只是调用一个函数。现有任务相当少,有些是异步的,有些是单个函数调用。
从一个操作完成到下一个操作开始需要多少时间?
What is the time involved from when one operation finishes and the
next operation begins?
下一个操作几乎立即开始。这个时间太小了,可以忽略。
Is there any other overheard to using Operation Queues?
OperationQueue
是一个非常有效的解决方案。
您可以通过设置属性来控制性能:
- qualityOfService:应用于使用队列执行的操作的默认服务级别。
- maxConcurrentOperationCount: 可以同时执行的最大排队操作数。
如果操作相互依赖,记得为它们设置这个关系
- addDependency(_ op: Operation):使接收者依赖指定操作的完成。
当你有这样的问题时,你可能只想测量一下。路标和兴趣点(使用 Instruments 来“分析”应用程序)是衡量性能的好方法。因此:
import os.signpost
let pointsOfInterest = OSLog(subsystem: "Operations", category: .pointsOfInterest)
并且:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
var id = OSSignpostID(log: pointsOfInterest)
queue.addOperation {
os_signpost(.begin, log: pointsOfInterest, name: "Operation", signpostID: id)
}
for _ in 0 ..< 100 {
queue.addOperation {
os_signpost(.end, log: pointsOfInterest, name: "Operation", signpostID: id)
id = OSSignpostID(log: pointsOfInterest)
os_signpost(.begin, log: pointsOfInterest, name: "Operation", signpostID: id)
}
}
queue.addOperation {
os_signpost(.end, log: pointsOfInterest, name: "Operation", signpostID: id)
}
我个人确保在进行这些测试之前让应用程序达到静止状态,通常只是将例程延迟几秒钟,这样可以减少标准应用程序启动开销,否则可能会改变结果。我还会对我的基准测试进行多次迭代,以获取更具代表性的结果集。
Profiling that with Instruments 的 Points of Interest 工具可以得到这组结果并为我们总结。例如,在我的 MacBook Pro 上的 iOS 模拟器 运行 上,它报告:
Min: 31.69 µs
Avg: 74.70 µs
StdDev: 24.05 µs
Max: 154.10 µs
在我的 iPhone XS Max 上:
Min: 44.92 µs
Average: 125.78 µs
StdDev: 43.61 µs
Max: 446.88 µs
您的里程可能会有所不同,但它以粗略的数量级说明了它所需要的开销。最重要的是,对于大多数用例来说,开销可以忽略不计。
如果您还有其他想要测试的场景,请随意。希望这能说明您如何使用 Instruments 中的兴趣点工具来衡量性能。有关详细信息,请参阅 Getting Started with Instruments。
我有一组异步操作且相互依赖的任务。现在所有这些都是用自定义代码管理的,我想改用 OperationQueue。然而,时序性能非常关键。
在当前的实现中,当一个任务完成时,它会立即调用所需的代码来启动下一个任务。所以所涉及的时间只是调用一个函数。现有任务相当少,有些是异步的,有些是单个函数调用。
从一个操作完成到下一个操作开始需要多少时间?
What is the time involved from when one operation finishes and the next operation begins?
下一个操作几乎立即开始。这个时间太小了,可以忽略。
Is there any other overheard to using Operation Queues?
OperationQueue
是一个非常有效的解决方案。
您可以通过设置属性来控制性能:
- qualityOfService:应用于使用队列执行的操作的默认服务级别。
- maxConcurrentOperationCount: 可以同时执行的最大排队操作数。
如果操作相互依赖,记得为它们设置这个关系
- addDependency(_ op: Operation):使接收者依赖指定操作的完成。
当你有这样的问题时,你可能只想测量一下。路标和兴趣点(使用 Instruments 来“分析”应用程序)是衡量性能的好方法。因此:
import os.signpost
let pointsOfInterest = OSLog(subsystem: "Operations", category: .pointsOfInterest)
并且:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
var id = OSSignpostID(log: pointsOfInterest)
queue.addOperation {
os_signpost(.begin, log: pointsOfInterest, name: "Operation", signpostID: id)
}
for _ in 0 ..< 100 {
queue.addOperation {
os_signpost(.end, log: pointsOfInterest, name: "Operation", signpostID: id)
id = OSSignpostID(log: pointsOfInterest)
os_signpost(.begin, log: pointsOfInterest, name: "Operation", signpostID: id)
}
}
queue.addOperation {
os_signpost(.end, log: pointsOfInterest, name: "Operation", signpostID: id)
}
我个人确保在进行这些测试之前让应用程序达到静止状态,通常只是将例程延迟几秒钟,这样可以减少标准应用程序启动开销,否则可能会改变结果。我还会对我的基准测试进行多次迭代,以获取更具代表性的结果集。
Profiling that with Instruments 的 Points of Interest 工具可以得到这组结果并为我们总结。例如,在我的 MacBook Pro 上的 iOS 模拟器 运行 上,它报告:
Min: 31.69 µs
Avg: 74.70 µs
StdDev: 24.05 µs
Max: 154.10 µs
在我的 iPhone XS Max 上:
Min: 44.92 µs
Average: 125.78 µs
StdDev: 43.61 µs
Max: 446.88 µs
您的里程可能会有所不同,但它以粗略的数量级说明了它所需要的开销。最重要的是,对于大多数用例来说,开销可以忽略不计。
如果您还有其他想要测试的场景,请随意。希望这能说明您如何使用 Instruments 中的兴趣点工具来衡量性能。有关详细信息,请参阅 Getting Started with Instruments。