【问题标题】:Why is calling system grep slower than matching in Ruby?为什么调用系统 grep 比在 Ruby 中匹配慢?
【发布时间】:2017-08-29 19:39:21
【问题描述】:

我正在编写一些代码,循环遍历项目中的所有 .rb 文件,并查看它们是否引用了 DateTime 类。我的第一次尝试是这样的:

file_names.each do |file_name|
  File.foreach(file_name) do |line|
    return file_name if line.match(/DateTime/)
  end
end

该算法的基准测试结果表明,运行 1100 个文件大约需要 0.6 秒,每个文件 25 次。不错,但我认为调用系统的grep 命令可能会更快。我的第二次尝试如下所示:

file_names.each do |file_name|
  return file_name if system("grep DateTime #{file_name} > /dev/null")
end

这需要 35.​​6 秒 运行!有没有人知道为什么第二次尝试表现如此糟糕?调用系统是慢部分还是 grep 比内部 ruby​​ 代码慢?

【问题讨论】:

  • 您的“第一次尝试”似乎不包含 file_names.each 循环。另外,你是哪里来的returning,一个方法?你怎么称呼它?两种尝试都会产生相同的结果吗?
  • grep 在处理多个文件时可能会更快,但在循环中使用时system 的开销相当大。
  • 尝试使用反引号从所有文件中捕获 grep 输出(例如,将它们放在一个命令中,而不是放在 ruby​​ 循环中)
  • 史蒂芬,好球。我更新了代码 sn-p。两种尝试都会产生相同的结果(这是一个包含 DateTime 的文件名数组)。我试图隐藏所有“其他代码”以保持问题简单。

标签: ruby


【解决方案1】:

向系统调用慢速部分的 grep 是否比内部 ruby​​ 代码慢?

在您的情况下,调用系统速度较慢。尤其是因为您为每个文件创建一个新的操作系统进程

这意味着 Ruby 必须要求操作系统创建 1100 个新的子进程(一次一个),并监视这些子进程是否终止。

由于 ruby​​ 中的所有文件 IO 都是用 C 编写的(至少在 mruby 中),因此您的 ruby​​ 脚本(它已经在运行它自己的操作系统进程并已分配系统内存)会更快,以打开文件并自行搜索,而不是创建 1100 个子进程。

【讨论】:

  • 感谢您的精彩解释。
猜你喜欢
  • 1970-01-01
  • 2015-10-05
  • 2015-06-10
  • 2013-03-17
  • 2014-10-14
  • 2010-10-20
  • 2018-11-10
  • 2013-08-12
  • 1970-01-01
相关资源
最近更新 更多