当您的工作是CPU 限制(CPU 完成工作,外围设备大部分空闲)但是在这里,您正在尝试提高任务的性能,该任务是I/O 限制(CPU 大部分时间处于空闲状态,等待繁忙的外设)。在这种情况下,增加并行性只会增加拥塞,因为多个任务将争夺它们之间已经匮乏的 I/O 带宽。
在 macOS 上,系统已经对您的所有数据进行了索引(包括文字处理文档、PDF、电子邮件等的内容);右上角的菜单栏上有一个友好的放大镜,您可以在其中访问更快、更通用的搜索,称为“Spotlight”。 (尽管我同意一些更复杂的控制find
缺失;当“用户友好”的设计猜测我想要什么并且猜测错误时,它就会妨碍我。)
一些 Linux 发行版提供类似的功能;我希望这成为当今任何带有 GUI 的标准,尽管系统之间的细节会有所不同。
在任何类 Unix 系统上更传统的解决方案是locate命令,执行类似但更有限的任务;它会在文件名上创建一个(非常快速的)索引,所以你可以说
locate fnord
非常快速地获取每个名称匹配的文件fnord
。索引只是一个结果的副本find
从昨晚开始运行(或者您安排后端运行)。该命令已安装在 macOS 上,但如果您想使用它,则必须启用后端。 (赶紧跑locate locate
以获得进一步的指示。)
例如,如果您发现自己经常寻找具有特定权限集和特定所有者的文件,您可以自己构建类似的东西(这些功能不是locate
记录);只需每晚(或每小时等)运行一次find
它将这些特征收集到数据库中,甚至只是文本文件中,然后您几乎可以立即进行搜索。
对于并行运行作业,您实际上并不需要 GNUparallel
,尽管它确实为许多用例提供了许多便利和增强功能;你已经拥有了xargs -P
. (The xargs
在源自 BSD 的 macOS 上比 GNU 受到更多限制xargs
你会在许多 Linux 上找到它;但它确实有-P
选项。)
例如,以下是如何运行八个并行find
实例与xargs -P
:
printf '%s\n' */ | xargs -I {} -P 8 find {} -name '*.ogg'
(这假设通配符与包含单引号或换行符或其他恶作剧的目录不匹配;GNUxargs
有-0
修复大量此类极端情况的选项;那么你会用'%s\0'
作为格式字符串printf
.)
As the parallel文档很容易解释,它的一般语法是
parallel -options command ...
where {}
将被替换为当前输入行(如果缺少,它将隐式添加到末尾)command ...
)和(显然是可选的):::
特殊标记允许您在命令行上指定输入源而不是标准输入。
这些特殊标记之外的任何内容都会逐字传递,因此您可以添加find
只需按字面指定即可随心所欲地选择选项。
parallel -j8 find {} -type f -name '*.ogg' ::: */
我不说话zsh
但针对常规 POSIX 进行了重构sh
你的函数可能是这样的
ff () {
parallel -j8 find {} -type f -iname "$2" ::: "$1"
}
尽管我可能会切换参数,以便您可以指定名称模式和要搜索的文件列表,à la grep
.
ff () {
# "local" is not POSIX but works in many sh versions
local pat=$1
shift
parallel -j8 find {} -type f -iname "$pat" ::: "$@"
}
但同样,您可能应该停止旋转磁盘来查找已索引的内容,而不是提供便利。