【问题标题】:Slowdown when processing large number of files in Ruby在 Ruby 中处理大量文件时速度变慢
【发布时间】:2016-04-28 06:44:55
【问题描述】:

我正在尝试创建一个包含大约 64000 个对象的大型数组。这些对象是文件的截断 SHA256 摘要。

文件位于 256 个子目录(名为 00 - ff)中,每个子目录包含大约 256 个文件(每个文件略有不同)。每个文件大小在 1.5KB 到 2KB 之间。

代码如下所示:

require 'digest'
require 'cfpropertylist'

A = Array.new

Dir.glob('files/**') do |dir|
    puts "Processing dir #{dir}"
    Dir.glob("#{dir}/*.bin") do |file|
        sha256 = Digest::SHA256.file file
        A.push(CFPropertyList::Blob.new(sha256.digest[0..7]))
    end
end

plist = A.to_plist({:plist_format => CFPropertyList::List::FORMAT_XML, :formatted => true})

File.write('hashes.plist', plist)

如果我处理 16 个目录(将上面的 'files/**' 替换为 'files/0*'),它在我的机器上花费的时间是 0m0.340s。

但是如果我尝试处理所有这些,在处理了大约 34 个目录后,处理速度会急剧下降。

这是在最新的 OS X 上,使用 stock ruby​​。 该机器是 2011 年中的 iMac,配备 12GB 内存和 3.4 GHz Intel Core i7。

限制因素似乎不是数组大小:因为如果我删除 sha256 处理并只存储文件名,则不会减速。

有什么我可以做得更好或跟踪问题的吗?我目前没有可用的其他操作系统或机器来测试这是否是 OS X 或机器特定的东西。

【问题讨论】:

  • “有什么我可以做的更好或跟踪问题”是的。使用 ruby​​-prof 对其进行分析。 github.com/ruby-prof/ruby-prof
  • meh,我发现它只是磁盘缓存。我必须在调试时多次运行该脚本,以便第一个文件在磁盘缓存中被处理并快速读取。在让脚本越来越长之后,减速发生的时间越来越晚。此外,那台机器有一个旋转磁盘。我在带有 SSD 的功能较弱的 Mac 上进行了尝试,即使在第一次运行时也没有发现速度变慢。

标签: ruby macos performance


【解决方案1】:

这是一个磁盘/FS 缓存问题。运行脚本完成并再次重新运行后,减速几乎消失了。使用另一台装有 SSD 的计算机也没有显示速度下降。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多