【问题标题】:Ruby zlib Library Very Slow to Decompress gzip FileRuby zlib 库解压 gzip 文件非常慢
【发布时间】:2016-10-14 02:00:35
【问题描述】:

我正在使用 Ruby 的 ZLib 库来解压缩一个很小的 ​​(10k) gzip 文件(在内存中使用 StringIO 类),它需要大约 2.5 秒来解压缩。压缩数据大约需要 100 毫秒,所以我不明白为什么解压缩的时间比压缩函数要长。

我的函数接受一个 StringIO 对象(包含压缩数据的内容)并返回一个由 (3 - 其中 '3' 由 int_size 参数定义的) 字节整数组成的数组,例如:

def decompress(io, int_size = 3)
  array = Array.new(262144)
  i = 0
  io.rewind
  gz = Zlib::GzipReader.new(io)
  until gz.eof?
    buffer = gz.read(int_size)
    array[i] = buffer.unpack('C*').inject { |r, n| r << 8 | n }
    i += 1
  end
  array
end

同一文件在 OSX 命令行中一眨眼就解压缩了。

是否有更快的解压缩文件的方法,或者更快的库或使用本地系统上的 gzip 的方法来实现这一点比现在快得多

【问题讨论】:

  • 尽可能使用系统工具,这些工具的效率惊人。它们经过超级优化且非常可靠。
  • 是的,我就是这么想的——但是我该怎么做呢?
  • 是的,出了点问题。在我四岁的 2 GHz i7 上解压缩 10K 大约需要 150 秒。

标签: ruby gzip zlib compression


【解决方案1】:

我不确定那里发生了什么(我仅使用高度压缩的 gzip 文件重现了缓慢),但一次解压缩更快,如下所示:

def decompress(io, int_size = 3)
    array = Array.new(262144)
    i = 0
    io.rewind
    gz = Zlib::GzipReader.new(io)
    dec = gz.read
    seq = StringIO.new(dec, "rb")
    until seq.eof?
        buffer = seq.read(int_size)
        array[i] = buffer.unpack('C*').inject { |r, n| r << 8 | n }
        i += 1
    end
    array
end

更快的是使用map 而不是循环:

def decompress(io, int_size = 3)
    io.rewind
    gz = Zlib::GzipReader.new(io)
    dec = gz.read
    dec.unpack('C*').each_slice(int_size).to_a.map {|t| t.inject {|r,n| r << 8 | n}}
end

【讨论】:

    【解决方案2】:

    你也可以使用ruby-zstds,它和gzip有类似的api。但是zstd压缩和解压非常快。请尝试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      • 2011-02-19
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      相关资源
      最近更新 更多