Files
clawhdf5/crates/clawhdf5-format/Cargo.toml
osobhandClaude Opus 5.5 78c769f179 perf(format): back large read buffers with transparent huge pages
A full read of a contiguous dataset is one memcpy from the mapped file,
yet ran at a quarter of h5py's speed on one thread: the fresh output Vec
took a page fault and a kernel page clear for every 4 KiB page written,
16384 per 64 MiB, costing several times the copy (the benchmark spent
6.2 s of 8 s in the kernel, 4.3M minor faults). numpy, so h5py, madvises
MADV_HUGEPAGE on allocations of 4 MiB or more; the typed readers' output,
the raw contiguous read and the chunk assembly buffer now do the same
(Linux only, libc as a Linux-only dependency; no-op otherwise).

New h5py comparison tests cover full and selection reads of contiguous
data for every 1-8-byte integer and float type, both byte orders, ranks
1-4, empty selections, and datasets past the 4 MiB threshold.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-26 08:12:55 -05:00

86 lines
3.3 KiB
TOML

[package]
name = "clawhdf5-format"
version = "2.7.0"
edition = "2024"
rust-version.workspace = true
description = "Pure-Rust HDF5 binary format parsing and writing — no C dependencies"
license = "MIT"
repository = "https://git.redclaw.dev/quantumclaw/clawhdf5"
readme = "README.md"
keywords = ["hdf5", "science", "data", "binary", "no-std"]
categories = ["parser-implementations", "science", "encoding", "no-std"]
[dependencies]
byteorder = { version = "1", default-features = false }
portable-atomic = { version = "1" }
flate2 = { version = "1", default-features = false, features = ["rust_backend"], optional = true }
sha2 = { version = "0.10", default-features = false, optional = true }
rayon = { version = "1", optional = true }
crc32fast = { version = "1", optional = true }
lz4_flex = { version = "0.11", optional = true }
zstd = { version = "0.13", optional = true }
blake3 = { version = "1", optional = true }
libaec-sys = { path = "../libaec-sys", version = "0.1", optional = true }
pco = { version = "1.0", optional = true }
# Pure-Rust Zstandard, for the plugin filters that embed zstd (bitshuffle,
# blosc). The `zstd` feature (filter 32015) links libzstd instead.
ruzstd = { version = "0.9", optional = true }
# bzip2 with its default backend, libbz2-rs-sys: a pure-Rust port of
# libbzip2 (no C is compiled, despite the -sys name).
bzip2 = { version = "0.6", optional = true }
snap = { version = "1", optional = true }
[target.'cfg(target_os = "linux")'.dependencies]
# madvise(MADV_HUGEPAGE) for large read buffers (see src/bulk_alloc.rs).
libc = { version = "0.2", default-features = false }
[dev-dependencies]
half = { workspace = true }
serde_json = "1"
criterion = { workspace = true }
clawhdf5-derive = { path = "../clawhdf5-derive", version = "2.7.0" }
[[bench]]
name = "bench"
harness = false
[features]
# Deflate backend: `zlib-rs` (pure Rust) by default. `fast-deflate` selects
# zlib-ng instead (C, built with cmake); flate2 prefers a C zlib whenever one
# is enabled, so turning it on anywhere in the build overrides the default.
default = ["std", "checksum", "deflate", "provenance", "zlib-rs", "system-zlib-decompress", "lzf"]
std = []
checksum = []
deflate = ["flate2"]
provenance = ["sha2"]
parallel = ["rayon", "std"]
fast-checksum = ["crc32fast"]
fast-deflate = ["flate2/zlib-ng"]
system-zlib = ["flate2/zlib-default"]
system-zlib-decompress = []
# `runtime_detection` gives zlib-rs `std`, which it needs to detect and use
# SIMD at runtime. flate2 enables it by default, but we build flate2 with
# default-features = false, and without it zlib-rs inflates 3.5x slower.
zlib-rs = ["flate2/zlib-rs", "flate2/runtime_detection"]
lz4 = ["lz4_flex"]
zstd = ["dep:zstd"]
blake3_hash = ["blake3"]
szip = ["libaec-sys"]
pcodec = ["dep:pco"]
# Plugin filters, pure Rust. LZF (32000) is h5py's built-in compression; it
# has no dependencies, so it is on by default.
lzf = []
# Bitshuffle (32008), with its LZ4 and Zstandard modes.
bitshuffle = ["lz4_flex", "ruzstd"]
# bzip2 (307).
bzip2 = ["dep:bzip2", "std"]
# Blosc 1 (32001) with its BloscLZ, LZ4, Snappy, Zlib and Zstandard codecs.
blosc = ["lz4_flex", "ruzstd", "snap", "deflate", "std"]
# Every plugin filter above.
plugin-filters = ["lzf", "bitshuffle", "bzip2", "blosc"]
[[bench]]
name = "parallel_decompress_bench"
harness = false
required-features = ["parallel"]