在Swift线程中限制CPU使用率

我想遍历 macOS 应用程序中潜在大目录的文件树。如果我只是这样做,我的示例案例大约需要 3 分钟,但 CPU 在这 3 分钟内飙升至 80% 左右。

我可以在后台线程上做得更慢,但我不确定最好的方法是什么。

我想只在循环中插入 1 毫秒睡眠,但我不确定这不会对调度/磁盘 IO 等产生负面影响。另一种方法是做 1 秒的工作,然后等待 2-3 秒,但我猜还有更优雅的东西吗?

我想要的核心功能是以嵌套方式遍历目录检查文件属性:

let enumerator = FileManager.default.enumerator(atPath: filePath)
while let element = enumerator?.nextObject() as? String {
     // do something here
 }

回答

通常,在短时间内使 CPU 尖峰比在较低水平下长时间运行更节能。只要您的进程的优先级低于其他进程,即使在短时间内以 100% 的速度运行 CPU 也不是问题(尤其是在不打开风扇的情况下)。现代 CPU 希望在短时间内非常努力地运行,然后完全空闲。长时间“有点忙”更糟糕,因为 CPU 无法关闭任何子系统。

即便如此,当用户看到 CPU 使用率很高时,他们会非常沮丧。我曾经从事系统管理软件的工作,我们与 Apple 讨论了限制 CPU 使用率的问题。他们告诉了我们上面的内容。我们说“是的,但是当用户看到我们以 100% 运行时,他们会向 IT 投诉并尝试卸载我们的应用程序。” Apple 的答案是使用sleep,就像您所描述的那样。如果它使您的过程需要更长的时间,那么它可能会对总能源使用产生负面的整体影响。但我不希望它造成任何其他麻烦。

也就是说,如果您不止一次扫描同一目录树,您应该查看文件系统事件和文件元数据搜索,它们可以更有效地执行此操作。

另请参阅:Mac 应用程序能效指南中的安排后台活动。我强烈推荐整个文档。近年来,macOS 中添加了许多工具,可能对您的问题有用。我还推荐在 WWDC 2017 上编写节能应用程序。

如果您确实需要使用枚举器直接扫描所有内容,则可以通过使用基于 URL 的 API而不是基于字符串的 API来极大地改进事情。它允许您预取某些值(包括attributeModificationDateKey,此处可能有用)。另外,请注意fileAttributesDirectoryEnumerator的属性,它缓存上次读取文件的属性(因此您无需再次查询它们)。

三分钟是很长的时间;可能你做的工作比需要的多。使用find命令行工具运行您的操作,并将其用作应该花费多长时间的基准。


以上是在Swift线程中限制CPU使用率的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>