Compression library for MoonBit: flate, gzip, zlib, lzw, bzip2, snappy, lz4, zstd, brotli
Dependencies
| Package | Description |
|---|---|
| bikallem/compress/flate | DEFLATE compression/decompression (RFC 1951) |
| bikallem/compress/flate/async | Async DEFLATE streaming via @io.Reader/@io.Writer |
| bikallem/compress/gzip | gzip format (RFC 1952) |
| bikallem/compress/zlib | zlib format (RFC 1950) |
| bikallem/compress/lzw | Lempel-Ziv-Welch (GIF/TIFF/PDF) |
| bikallem/compress/brotli | Brotli compression/decompression (RFC 7932) |
| bikallem/compress/bzip2 | bzip2 compression/decompression |
| bikallem/compress/zstd | Experimental Zstandard frame compression/decompression with dictionary support |
| bikallem/compress/lz4 | LZ4 frame compression/decompression for independent-block frames |
| bikallem/compress/checksum | CRC-32 and Adler-32 checksums |
moon add bikallem/compress// DEFLATE (level defaults to DefaultCompression)
let compressed = @flate.compress(data)
let compressed = @flate.compress(data, level=BestSpeed)
let decompressed = @flate.decompress(compressed)
// gzip
let compressed = @gzip.compress(data)
let compressed = @gzip.compress(data, level=BestCompression, header={ name: "data.txt", ..Header::default() })
let (decompressed, header) = @gzip.decompress(compressed)
// zlib (supports preset dictionaries)
let compressed = @zlib.compress(data)
let compressed = @zlib.compress(data, dict=my_dict, level=BestSpeed)
let decompressed = @zlib.decompress(compressed)
// LZW
let compressed = @lzw.compress(data, LSB, 8)
let decompressed = @lzw.decompress(compressed, LSB, 8)
// Brotli (level 0-11)
let compressed = @brotli.compress(data)
let compressed = @brotli.compress(data, level=Level(1))
let decompressed = @brotli.decompress(compressed)
// bzip2 (level 1-9, controls block size)
let compressed = @bzip2.compress(data)
let compressed = @bzip2.compress(data, level=9)
let decompressed = @bzip2.decompress(compressed)
// Zstandard
let compressed = @zstd.compress(data)
let compressed = @zstd.compress(data, level=Fast)
let compressed = @zstd.compress(data, dict=my_zstd_dict)
let decompressed = @zstd.decompress(compressed)
let decompressed = @zstd.decompress(compressed, dict=my_zstd_dict)
// LZ4 (independent-block frames)
let compressed = @lz4.compress(data)
let decompressed = @lz4.decompress(compressed)
// Checksums
let crc = @checksum.crc32(data[:])
let adler = @checksum.adler32(data[:])let d = @flate.Deflater::new(level=BestSpeed)
match d.encode(Some(data[:])) {
Ok => () // input buffered, no output yet
Data(out) => ... // compressed output ready
End => ... // shouldn't happen mid-stream
Error(e) => ... // compression error
}
loop d.encode(None) {
Data(out) => { write(out); continue d.encode(None) }
End => break
Ok | Error(_) => break
}let d = @flate.Inflater::new()
d.src(compressed_chunk[:])
loop d.decode() {
Await => { d.src(next_chunk[:]); continue d.decode() }
Data(out) => { write(out); continue d.decode() }
End => break
Error(e) => ...
}// gzip with custom header
let d = @gzip.Deflater::new(header={ name: "data.txt", ..Header::default() })
// Access the header after decompression
let header = inflater.header()
// zlib with preset dictionary
let d = @zlib.Deflater::new(dict=my_dict)
let i = @zlib.Inflater::new(dict=my_dict)
// LZW with bit order and literal width
let d = @lzw.Deflater::new(MSB, 8)
let i = @lzw.Inflater::new(MSB, 8)
// Brotli
let d = @brotli.Deflater::new(level=Level(6))
let i = @brotli.Inflater::new()
// bzip2
let d = @bzip2.Deflater::new(level=9)
let i = @bzip2.Inflater::new()
// Zstandard
let d = @zstd.Deflater::new(level=Fast, dict=my_zstd_dict)
let i = @zstd.Inflater::new(dict=my_zstd_dict)
// LZ4 (buffered wrapper, independent-block frames only)
let d = @lz4.Deflater::new()
let i = @lz4.Inflater::new()
// Get remaining unprocessed input after decompression
let leftover = inflater.remaining()// Async DEFLATE compression
async fn compress_stream(reader : &@io.Reader, writer : &@io.Writer) -> Unit {
@flate.async.compress(reader, writer, level=BestSpeed)
}
// Async DEFLATE decompression
async fn decompress_stream(reader : &@io.Reader, writer : &@io.Writer) -> Unit {
@flate.async.decompress(reader, writer)
}| Level | Description |
|---|---|
| NoCompression | Store blocks only (level 0) |
| BestSpeed | Fastest compression (level 1) |
| Level(2..8) | Trade-off between speed and ratio |
| BestCompression | Smallest output (level 9) |
| DefaultCompression | Balanced default (level 6) |
| HuffmanOnly | Huffman encoding, no LZ77 matching |
let h = @checksum.CRC32::new()
h.update(chunk1[:])
h.update(chunk2[:])
let result = h.checksum()| Benchmark | MoonBit | Go | Ratio |
|---|---|---|---|
| compress 1 KB | 16 µs | 67 µs | 0.24x |
| compress 10 KB | 63 µs | 124 µs | 0.51x |
| compress 100 KB | 570 µs | 298 µs | 1.91x |
| compress 1 MB | 6.2 ms | 2.0 ms | 3.06x |
| compress speed 1 KB | 12 µs | 134 µs | 0.09x |
| compress speed 10 KB | 15 µs | 125 µs | 0.12x |
| decompress 1 KB | 0.82 µs | 4.0 µs | 0.21x |
| decompress 10 KB | 5.1 µs | 10.7 µs | 0.47x |
| decompress 100 KB | 29 µs | 58 µs | 0.50x |
| decompress 1 MB | 305 µs | 915 µs | 0.33x |
| decompress 10 MB | 4.8 ms | 10.5 ms | 0.46x |
| Benchmark | MoonBit | Go | Ratio |
|---|---|---|---|
| compress 1 KB | 54 µs | 754 µs | 0.07x |
| compress 10 KB | 500 µs | 2,047 µs | 0.24x |
| compress 100 KB | 5.4 ms | 10.2 ms | 0.53x |
| compress 1 MB | 107 ms | 112 ms | 0.95x |
| decompress 1 KB | 123 µs | 420 µs | 0.29x |
| decompress 10 KB | 167 µs | 541 µs | 0.31x |
| decompress 100 KB | 680 µs | 1,225 µs | 0.55x |
| decompress 1 MB | 6.0 ms | 7.2 ms | 0.83x |
| Benchmark | MoonBit | Go | Ratio |
|---|---|---|---|
| compress 1 KB | 7.4 µs | 8.6 µs | 0.86x |
| compress 10 KB | 41 µs | 42 µs | 0.98x |
| compress 100 KB | 424 µs | 427 µs | 0.99x |
| compress 1 MB | 4.6 ms | 4.3 ms | 1.05x |
| decompress 1 KB | 3.7 µs | 4.7 µs | 0.78x |
| decompress 10 KB | 16 µs | 26 µs | 0.63x |
| decompress 100 KB | 140 µs | 244 µs | 0.57x |
| decompress 1 MB | 1.6 ms | 2.7 ms | 0.57x |
Compression library for MoonBit: flate, gzip, zlib, lzw, bzip2, snappy, lz4, zstd, brotli
Dependencies