我有一个正在尝试迁移到新项目的应用程序。我在主线程中异步处理了一个繁重的操作。在我的旧项目中,完成这项任务只需要一秒钟,但在我的新项目中,同样的任务需要6-7 秒。
我观察了 CPU 使用率,看起来新应用程序使用的 CPU 较少,线程数很少,而旧应用程序为同一任务获得大量线程。PS:我使用的是相同的设备。
什么可能导致这种情况?有什么想法或建议要找出来吗?
谢谢。
我有一个正在尝试迁移到新项目的应用程序。我在主线程中异步处理了一个繁重的操作。在我的旧项目中,完成这项任务只需要一秒钟,但在我的新项目中,同样的任务需要6-7 秒。
我观察了 CPU 使用率,看起来新应用程序使用的 CPU 较少,线程数很少,而旧应用程序为同一任务获得大量线程。PS:我使用的是相同的设备。
什么可能导致这种情况?有什么想法或建议要找出来吗?
谢谢。
最后,我发现了问题。这是由Optimization Level
Xcode 中的设置引起的Build Settings
。创建新项目时,默认Debug
优化级别为none
,Release
优化级别为Fastest, Smallest [-Os]
So 当我将 Debug 更改为Fastest, Smallest [-Os]
我的任务完成时间下降到 1 秒。
来自苹果:
Xcode 编译器支持优化选项,让您可以选择更小的二进制大小、更快的代码还是更快的构建时间。对于新项目,Xcode 会自动禁用调试构建配置的优化,并为发布构建配置选择最快、最小选项。由于优化过程中涉及的额外工作,任何类型的代码优化都会导致构建时间变慢。如果您的代码正在更改,就像在开发周期中所做的那样,您不希望启用优化。但是,当您接近开发周期的尾声时,发布构建配置可以为您提供成品大小的指示,因此“最快、最小”选项是合适的。
如果您想阅读有关优化级别和性能的更多信息:调整性能和响应性
旁注:在调试模式下将优化级别更改为最快、最小 [-0s] 可能会影响调试器断点,并且会突然运行。
干杯。
这可能不是对你问题的真正回应,你自己回答得很好,但我觉得它是必要的。
我想强调一下你不应该在主线程上进行长时间运行的操作。没原因。实际上,如果您希望屏幕每秒刷新 60 次(这应该始终是您的目标),这意味着您提交给主线程的每个代码块必须持续少于 0.016 秒(1/60)以避免丢失一些帧. 如果与此同时,您还需要让主线程执行一些复杂的动画和其他操作,那么您可能需要远远落后于 0.016 秒这一点。
如果您阻塞主线程的时间远远超过(在这种情况下为 1 秒),用户将体验到卡住的界面,他们将无法滚动滚动视图或导航应用程序。他们可能会完全关闭您的应用程序,因为他们可能会觉得它被卡住了。
例如,在您的情况下,您可能想要添加一些不错的加载动画,例如 ActivityIndicator 或一些更好的动画,以表达您当时实际上正在工作并且您没有冻结。这确实是当今用户所期望的。如果用户想要取消长时间运行的操作并对您的应用程序执行其他操作,您可能(也可能不会,这取决于您)还想添加一个取消按钮。
为避免您所说的导致性能损失(任务减慢至 7-8 秒),您可能需要使用具有高质量服务的 serialQueue 。可能userInitiated是您想要的。
这样,您仍然可以让操作系统优先处理这些任务,但同时您不会阻塞主线程,例如允许您添加加载动画。
如果性能仍然太低,您可以考虑将任务拆分为子任务并使用DispatchQueue.concurrentPerform(iterations:execute:)并行执行(但我不知道这在您的情况下是否可行)。
我希望这可以帮助你。干杯