Ruby zlib库解压gzip文件非常慢



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

我的函数接受一个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的方法来实现这一点比现在快得多 ?

我不确定那里发生了什么(我只使用高度压缩的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

您也可以使用ruby-zstds,它具有与gzip类似的api。但zstd的压缩和解压速度非常快。请试一试。

最新更新