Ruby zlib 库解压 gzip 文件非常慢
Posted
技术标签:
【中文标题】Ruby zlib 库解压 gzip 文件非常慢【英文标题】:Ruby zlib Library Very Slow to Decompress gzip File 【发布时间】: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 的方法来实现这一点比现在快得多?
【问题讨论】:
尽可能使用系统工具,这些工具的效率惊人。它们经过超级优化且非常可靠。 是的,我就是这么想的——但是我该怎么做呢? blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html 是的,出了点问题。在我四岁的 2 GHz i7 上解压缩 10K 大约需要 150 微 秒。 【参考方案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
压缩和解压非常快。请尝试。
【讨论】:
以上是关于Ruby zlib 库解压 gzip 文件非常慢的主要内容,如果未能解决你的问题,请参考以下文章