La biblioteca pgzip, desarrollada en Go, ofrece una solución para compresión y descompresión en paralelo utilizando el formato estándar gzip. Funciona como un reemplazo directo de la biblioteca nativa compress/gzip
, pero con mejoras significativas en rendimiento y concurrencia, especialmente para grandes volúmenes de datos.
¿Por qué usar pgzip?
- Procesamiento en paralelo: Divide la compresión en bloques para acelerar el proceso.
- Compatible con gzip estándar: Los archivos comprimidos con pgzip pueden ser leídos por cualquier lector de gzip.
- Descompresión eficiente: Permite la lectura anticipada (readahead), evitando bloqueos en la ejecución del código.
- Optimización en CPU multinúcleo: Aprovecha el hardware para maximizar la velocidad de compresión y descompresión.
- Manejo automático de CRC: La verificación de integridad se ejecuta en un hilo separado, mejorando la eficiencia.
Instalación
Para instalar la biblioteca, ejecuta:
go get github.com/klauspost/pgzip/...
También es recomendable actualizar las dependencias:
go get -u github.com/klauspost/compress
Uso de pgzip en Go
Compresión en paralelo
pgzip se usa de manera similar a compress/gzip
, con la opción adicional de configurar el tamaño de bloque y la cantidad de bloques en paralelo.
package main
import (
"bytes"
"compress/gzip"
"os"
"github.com/klauspost/pgzip"
)
func main() {
var b bytes.Buffer
w := pgzip.NewWriter(&b)
// Configurar concurrencia: 100 KB por bloque y hasta 10 bloques en paralelo.
w.SetConcurrency(100000, 10)
w.Write([]byte("Hola, mundo\n"))
w.Close()
// Guardar el archivo comprimido
os.WriteFile("archivo.gz", b.Bytes(), 0644)
}
Explicación:
SetConcurrency(blockSize, blocks)
: Define el tamaño de bloque y el número de bloques en paralelo.- Valores recomendados:
- Tamaño mínimo de bloque: 100 KB.
- Número de bloques: Aproximadamente el doble del número de núcleos de la CPU.
Para notar mejoras de rendimiento, se recomienda comprimir archivos de más de 1 MB.
Descompresión en paralelo
La descompresión con pgzip es similar a compress/gzip
, con la ventaja de permitir readahead (lectura anticipada) para mejorar el rendimiento.
package main
import (
"os"
"github.com/klauspost/pgzip"
)
func main() {
f, err := os.Open("archivo.gz")
if err != nil {
panic(err)
}
defer f.Close()
r, err := pgzip.NewReader(f)
if err != nil {
panic(err)
}
defer r.Close()
contenido, err := os.ReadFile("archivo.gz")
if err != nil {
panic(err)
}
os.WriteFile("archivo.txt", contenido, 0644)
}
Si se necesita un control más preciso sobre la concurrencia, se puede usar:
r, err := pgzip.NewReaderN(f, blockSize, blocks)
Donde:
blockSize
define el tamaño de los bloques a decodificar.blocks
define la cantidad de bloques a decodificar por adelantado.
Comparación de Rendimiento
Compresión (CPU de 16 núcleos, GOMAXPROC=32)
Comprimidor | Velocidad (MB/s) | Aceleración | Tamaño final | Sobrecarga (%) |
---|---|---|---|---|
gzip (Go estándar) | 16.91 MB/s | 1.0x | 4.78 GB | 0% |
gzip (klauspost) | 127.10 MB/s | 7.52x | 4.88 GB | +2.17% |
pgzip (klauspost) | 2085.35 MB/s | 123.34x | 4.88 GB | +2.19% |
Observaciones:
- pgzip es 123 veces más rápido que gzip estándar en esta prueba.
- La sobrecarga en el tamaño del archivo es mínima (+2.19%) en comparación con gzip.
- pgzip incluye un modo de compresión Huffman, que permite velocidades de hasta 450 MB/s por núcleo.
Descompresión (CPU de 4 núcleos)
Descompresor | Tiempo | Aceleración |
---|---|---|
gzip (Go estándar) | 1m 28.85s | 1.0x |
pgzip (klauspost) | 43.48s | 2.04x |
Conclusión:
- pgzip es más del doble de rápido que gzip estándar.
- La lectura anticipada (readahead) permite que los datos se procesen más rápido sin bloqueos de I/O.
- La implementación actúa como buffer, evitando esperas innecesarias.
Conclusión
pgzip es una excelente opción para aplicaciones en Go que requieren compresión y descompresión eficiente en paralelo, especialmente en entornos de alto rendimiento. Sus principales ventajas incluyen:
✅ Compatible con gzip estándar: No requiere cambiar herramientas o formatos.
✅ Optimizado para grandes volúmenes de datos: Acelera procesamiento de archivos de más de 1 MB.
✅ Soporte para CPU multinúcleo: Aprovecha el hardware para maximizar velocidad.
✅ Compresión Huffman para ultra-rendimiento: Hasta 450 MB/s por núcleo.
✅ Mejor rendimiento que gzip en Go: Hasta 123x más rápido en compresión y 2x más rápido en descompresión.
Si trabajas con grandes volúmenes de datos y necesitas compresión/descompresión eficiente en Go, pgzip es la mejor opción. 🚀