Estoy usando la biblioteca ZLib de Ruby para descomprimir unarchivo gzip pequeño (10k) (en memoria usando una clase StringIO) y su descompresión tarda aproximadamente 2.5 segundos. La compresión de los datos tarda ~ 100 ms, por lo que no entiendo por qué la descompresión tarda más que la función de compresión.
Mi función toma un objeto StringIO (con el contenido de los datos comprimidos) y devuelve una matriz de (3 - donde "3" se define por el entero int_size) bytes, como:
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
El mismo archivo se descomprime en la línea de comando OSX en un abrir y cerrar de ojos.
¿Existe una forma más rápida de descomprimir el archivo, o tal vez una biblioteca más rápida o una forma de usar el gzip en el sistema local para que esto suceda? mucho más rápido de lo que es ahora?
Respuestas
0 para la respuesta № 1No estoy seguro de lo que está sucediendo allí (reproduje la lentitud solo con un archivo gzip altamente comprimido), pero descomprimir todo a la vez es más rápido, algo como esto:
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
Más rápido aún sería usar map
en lugar de un bucle:
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