【问题标题】:How to determine which choice of one-line scripts is faster in BASH?如何判断 BASH 中选择哪一种单行脚本更快?
【发布时间】:2014-12-22 12:18:53
【问题描述】:

我有一个脚本在一周内运行了几百万次,它只是在名为 file.csv 的 CSV 文件中找到与 $word 完全匹配的第一个单元格,并打印整行,例如CSV:

robot@mechanical@a machine that does automated work
fish@animal@an animal that lives in the sea
tree@plant@a plant that grows in the forest

如果搜索“树”,则会打印:

tree@plant@a plant that grows in the forest

这两种方法得到相同的结果:

awk -F@ -v pattern="$word" '$1 ~ "^" pattern "$" {print; exit}' file.csv

grep ^$word@ file.csv | head -1

同样,这可用于检查 CSV 的第二列中的完全匹配,假设有 3 列:

awk -F@ -v pattern="$word" '$2 ~ "^" pattern "$" {print; exit}' file.csv

grep ^.*@$word@.*@.*$ file.csv | head -1

如果选择两个脚本,例如上面的这个示例,它们总是产生完全相同的输出,我如何快速确定哪个更快?

【问题讨论】:

  • 这里还需要注意的是,grep -m 1 在大多数情况下肯定会比grep | head -n 1 快。
  • 另外,第二个grep 的更好正则表达式是"^[^@]*@$word@",它也更好地匹配Awk 表达式。

标签: bash optimization


【解决方案1】:

您可以通过测量来确定哪个更快。 time 命令是您的第一站。

你应该安排什么时间?你如何定义“快速”?这显然取决于,但如果您希望大多数单词匹配,您可以计算文件中最中间的行需要多长时间。假设您在 CSV 文件中有 999 行,第 499 行唯一包含“gollum”;

time grep -m 1 '^gollum@' file.csv >/dev/null
time awk -F @ '$1 ~ "gollum" { print; exit }' file >/dev/null

线的长度不是大致均匀吗?您是否主要期望搜索失败?文件开头附近的大多数匹配项?然后相应地调整您的实验。

一个常见的警告是磁盘 I/O 缓存将使重新运行更快。为了获得可比较的结果,请始终先执行虚拟运行,以确保为实际运行填充缓存。可能会重新运行每个实验几次,以便平均系统负载的临时变化等。

你也可以解释你的问题。在其他条件相同的情况下,我希望 grep 更快,因为它在启动期间和处理每个输入行时都进行较少的解析。但有时在其中一个或另一个中进行优化(或者选择不当的表达方式,最终将苹果与橙子进行比较,如您上次的 grep 中)会抛出这种常识性的结果。

【讨论】:

【解决方案2】:

如果您真的关心效率,那么避免使用正则表达式进行精确匹配并将两个命令都用作:

awk -F'@' -v pattern="$word" '$1 == pattern{print; exit}' file.csv

grep -m1 -F "$word@" file.csv

要进行一些基准测试,请使用time 命令:

time awk -F'@' -v pattern="$word" '$1 == pattern{print; exit}' file.csv

time grep -m1 -F "$word@" file.csv

【讨论】:

  • grep -m 1 -F "$word@" file.csv 应该比管道 grephead 更好。
  • 谢谢肯定-m 1 会比管道命令更好。
  • 但限制为第一个匹配是 OP 在问题中显示的内容。
  • @tripleee "在名为 file.csv 的 CSV 文件中找到与 $word 完全匹配的第一个单元格,并打印整行" |head -1 {print; exit} 都直接与您的阅读相矛盾。
  • @sehe 我的错——我的阅读草率。将相应地更新我自己的答案。 (我在想“第一个单元格”只是指该行的第一个字段。)
【解决方案3】:

让它们在您的文件上循环运行约 1mio 次,并打印两个脚本所需的时间(结束 - 开始)。一个会比另一个快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 2011-03-27
    • 2019-05-21
    相关资源
    最近更新 更多