Zstandard Compression in Go: A High-Performance Library

The Zstandard (Zstd) compression algorithm, known for its real-time, high-ratio compression, has been implemented in pure Go by the open-source repository klauspost/compress. This implementation prioritizes speed and efficiency, offering various levels of compression and optimized performance, particularly on 64-bit processors.


Why Use Zstd for Compression?

Zstd is designed to balance speed and compression ratio, making it ideal for scenarios requiring fast processing with significant storage savings. Key advantages include:

  • High-speed encoding and decoding: Outperforms traditional compression methods like gzip and deflate.
  • Multiple compression levels: From Fastest (level 1) to Best (level 11), allowing users to choose between speed and compression ratio.
  • Concurrent processing: Supports multi-threading with the ability to control concurrency levels.
  • Memory-efficient: Designed to minimize allocations and reuse encoders/decoders for optimal performance.

Installing and Using the Zstd Go Library

Installation

To install the Zstd compression library in Go, simply run:

go get -u github.com/klauspost/compress

This package is located at:

github.com/klauspost/compress/zstd

Using the Zstd Encoder in Go

For compressing a stream of data, the following function initializes a Zstd writer and processes the input:

package main

import (
    "io"
    "os"
    "github.com/klauspost/compress/zstd"
)

func Compress(in io.Reader, out io.Writer) error {
    enc, err := zstd.NewWriter(out)
    if err != nil {
        return err
    }
    _, err = io.Copy(enc, in)
    if err != nil {
        enc.Close()
        return err
    }
    return enc.Close()
}
  • The NewWriter() function initializes the Zstd encoder.
  • Data is compressed and written to the output stream.
  • Close() ensures resources are properly released.

For small encodings, the EncodeAll() method is preferred, which compresses a given byte slice:

var encoder, _ = zstd.NewWriter(nil)

func CompressBuffer(src []byte) []byte {
    return encoder.EncodeAll(src, make([]byte, 0, len(src)))
}

Using the Zstd Decoder in Go

For decompressing a stream, initialize a Zstd reader as follows:

func Decompress(in io.Reader, out io.Writer) error {
    d, err := zstd.NewReader(in)
    if err != nil {
        return err
    }
    defer d.Close()

    _, err = io.Copy(out, d)
    return err
}

For buffer decompression, use:

var decoder, _ = zstd.NewReader(nil)

func DecompressBuffer(src []byte) ([]byte, error) {
    return decoder.DecodeAll(src, nil)
}

Performance and Benchmarking

Benchmarks show that Zstd is significantly faster than gzip while achieving better compression ratios.

Example Performance on Large Files:

FileCompression LevelInput SizeOutput SizeTime (ms)Speed (MB/s)
silesia.tarLevel 1 (Fastest)211 MB73 MB634 ms318 MB/s
silesia.tarLevel 4 (Best)211 MB60 MB16,926 ms11.94 MB/s
gob-streamLevel 1 (Fastest)1.9 GB233 MB3,230 ms564 MB/s
gob-streamLevel 4 (Best)1.9 GB162 MB47,559 ms38 MB/s
  • At fastest settings, Zstd runs twice as fast as gzip.
  • At best compression, Zstd reduces storage by ~70-80% but requires more processing time.

Advanced Features

  1. Concurrency Control
    • WithEncoderConcurrency(n): Defines the number of goroutines used for parallel compression.
    • WithDecoderConcurrency(n): Limits decompression threads to prevent excessive CPU usage.
  2. Dictionary Compression
    • Supports pre-trained dictionaries to improve compression for structured data.
    • Use WithEncoderDict(dict []byte) and WithDecoderDicts(dicts ...[]byte) to enable dictionary compression.
  3. Streaming and Buffer-Based Encoding
    • Supports real-time encoding with minimal resource consumption.
    • Reuses encoders/decoders to reduce memory allocations.

Conclusion

Zstd in Go, as implemented by klauspost/compress, provides a powerful, efficient, and flexible compression solution. With high-speed processing, configurable concurrency, and advanced compression settings, it is well-suited for applications handling large datasets, real-time processing, and cloud storage optimizations.

For developers needing fast and high-ratio compression, Zstd is a superior choice over gzip.

Scroll to Top