swift - 在 Swift 线程中限制 CPU 使用率
问题描述
我想遍历文件树以查找 macOS 应用程序中可能很大的目录。如果我只是这样做,我的示例案例大约需要 3 分钟,但在这 3 分钟内 CPU 会飙升至 80% 左右。
我可以负担得起在后台线程上更慢地执行此操作,但不确定最好的方法是什么。
我想在循环中插入 1 毫秒睡眠,但我不确定这不会对调度/磁盘 IO 等产生负面影响。另一种方法是做 1 秒的工作,然后等待 2-3 秒,但我猜还有更优雅的东西?
我想要的核心功能是以嵌套方式遍历目录检查文件属性:
let enumerator = FileManager.default.enumerator(atPath: filePath)
while let element = enumerator?.nextObject() as? String {
// do something here
}
解决方案
通常,在短时间内使 CPU 达到峰值比在较长时间内以低电平运行 CPU 是最节能的。只要您的进程的优先级低于其他进程,即使在短时间内以 100% 的速度运行 CPU 也不是问题(特别是如果它没有打开风扇)。现代 CPU 希望在短时间内非常努力地运行,然后完全空闲。较长时间的“有点忙”会更糟,因为 CPU 无法关闭任何子系统。
即便如此,当用户看到高 CPU 使用率时,他们还是会非常沮丧。我曾经从事系统管理软件的工作,我们与 Apple 讨论了限制我们的 CPU 使用率的问题。他们告诉我们以上。我们说“是的,但是当用户看到我们在 100% 运行时,他们会向 IT 投诉并尝试卸载我们的应用程序。” Apple 的答案是使用sleep
,就像您所描述的那样。如果它使您的过程花费更长的时间,那么它可能会对总能源使用产生负面的整体影响。但我不认为它会引起任何其他麻烦。
也就是说,如果您多次扫描同一个目录树,您应该查看文件系统事件和文件元数据搜索,它们可以更有效地执行此操作。
另请参阅:Mac 应用程序能效指南中的计划后台活动。我强烈推荐整个文档。近年来,macOS 中添加了许多可能对您的问题有用的工具。我还建议从 WWDC 2017编写节能应用程序。
如果您确实需要使用枚举器直接扫描所有内容,则可以通过使用基于 URL 的 API而不是基于字符串的 API 来极大地改进事情。它允许您预取某些值(包括attributeModificationDateKey
,可能在此处使用)。另外,请注意fileAttributes
DirectoryEnumerator 的属性,它缓存最后读取文件的属性(因此您无需再次查询它们)。
三分钟是很长的时间;有可能你做的工作比需要的多。使用命令行工具运行您的操作,find
并将其用作应该花费多少时间的基准。
推荐阅读
- java - 将按钮添加到listview firebase arraylist strings android
- c - 如何在编译时定义由来自不同模块的静态(私有)结构组成的结构数组?
- c# - 如何在水晶报表中隐藏一个部分
- html - Gitignore 生成的 pdf 但不是所有的 pdf
- clojure - Clojure 和 Leiningen:为什么在这个例子中需要 `doall`?
- c# - 如何使用 openfiledialog 在 C# 中以文本形式打开任何文件?
- python - 为什么这个 python 代码会使我的网站崩溃?而这个其他python代码没有?
- c++ - C++,处理多个构造函数重载和冗余代码
- python - 使用 bool(TheClassItself) 返回 False 的类
- excel - 对字符串的出现求和