Ruby zlib 库解压缩 gzip 文件非常慢
Ruby zlib Library Very Slow to Decompress gzip File
我正在使用 Ruby 的 ZLib 库解压缩一个较小的 (10k) gzip 文件(在内存中使用 StringIO class),解压缩大约需要 2.5 秒。压缩数据需要大约 100 毫秒,所以我不明白为什么解压缩比压缩功能花费的时间长得多。
我的函数接受一个 StringIO 对象(包含压缩数据的内容)和 returns 一个数组(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
压缩和解压都非常快。请尝试。
我正在使用 Ruby 的 ZLib 库解压缩一个较小的 (10k) gzip 文件(在内存中使用 StringIO class),解压缩大约需要 2.5 秒。压缩数据需要大约 100 毫秒,所以我不明白为什么解压缩比压缩功能花费的时间长得多。
我的函数接受一个 StringIO 对象(包含压缩数据的内容)和 returns 一个数组(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
压缩和解压都非常快。请尝试。