2017-08-29 80 views
0

我正在编写一些代码,循环遍历项目中的所有.rb文件,看看它们是否引用DateTime类。我第一次尝试是这样的:为什么调用系统grep比在Ruby中匹配要慢?

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

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

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

这需要35.6秒跑!有没有人有任何洞察,为什么第二次尝试表现如此糟糕?调用系统是缓慢的部分还是grep比内部ruby代码慢?

+1

您的“第一次尝试”似乎不包含'file_names.each'循环。此外,你从哪里返回,一个方法?你怎么称呼它?这两种尝试都会产生相同的结果吗? – Stefan

+1

在处理多个文件时'grep'可能会更快,但是当在循环中使用时,'system'的开销很大。 – tadman

+0

尝试使用反引号从所有文件中捕获grep输出(例如,将它们放在一个命令中,而不是在一个红宝石循环中) –

回答

6

对系统调用slow partor是grep比内部ruby代码慢吗?

在你的情况下,调用系统比较慢。特别是因为你如何为每个文件创建一个新的OS进程

这意味着Ruby不得不要求操作系统创建1100个新的子进程(一次一个),并监视这些子进程的终止。因为ruby中的所有文件IO都是以C语言编写的(至少在mruby中),所以ruby脚本(它已经运行它自己的OS进程并分配了系统内存)会更快一些,打开文件并自行搜索,而不是创建1100个子进程。

+0

谢谢你的解释。 – CodeSmith