Skip to content

feat: Switch to WASM based crypto and compression implementations.#213

Merged
mcollina merged 1 commit intomainfrom
wasm
Feb 20, 2026
Merged

feat: Switch to WASM based crypto and compression implementations.#213
mcollina merged 1 commit intomainfrom
wasm

Conversation

@ShogunPanda
Copy link
Copy Markdown
Contributor

No description provided.

Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include the benchmarks in the description too.

How big are the final wasm files?

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread native/Makefile.toml Outdated
@ShogunPanda ShogunPanda requested a review from mcollina February 10, 2026 14:44
@ShogunPanda
Copy link
Copy Markdown
Contributor Author

Include the benchmarks in the description too.

How big are the final wasm files?

Just one file, 75KB.

@mcollina
Copy link
Copy Markdown
Member

CI is red

@mcollina
Copy link
Copy Markdown
Member

Benchmark Results

CRC32C:

Implementation ops/sec vs previous
kafkajs 48,584 baseline
JS 86,841 +78.75%
WASM 138,741 +59.76%
@node-rs/crc32 159,278 +14.80% (fastest)

LZ4:

Implementation ops/sec vs previous
native 63,775 baseline
wasm 90,943 +42.60%

Snappy:

Implementation ops/sec vs previous
native 67,805 baseline
wasm 135,612 +100% (2x faster)

The WASM implementations outperform native for both LZ4 and Snappy compression.

@mcollina
Copy link
Copy Markdown
Member

CRC32C WASM Optimization Analysis

I investigated whether the WASM CRC32C implementation can be optimized to match @node-rs/crc32 performance.

Current Performance Gap

Implementation ops/sec vs WASM
JS ~11,400 baseline
WASM ~87,000 7.6x faster
@node-rs/crc32 ~660,000 7.6x faster than WASM

The gap is consistent across buffer sizes (64B to 16KB).

Why WASM Can't Match Native

  • @node-rs/crc32 uses hardware CRC32 instructions (SSE4.2 on x86, CRC extension on ARM)
  • WASM has no equivalent hardware CRC instruction
  • WASM SIMD (simd128) exists but lacks:
    • CRC32 instruction
    • CLMUL (carry-less multiply) used for parallel CRC computation

Alternatives Explored

  1. crc-fast - Claims >100GiB/s but only with hardware acceleration. WASM build falls back to table-based (same as current)
  2. WASM SIMD - Portable SIMD doesn't compile well to wasm32; manual core::arch::wasm32 intrinsics lack CRC-relevant operations
  3. Current crc32c crate - Already uses optimized table-based approach for software fallback

Conclusion

The WASM CRC32C implementation is at the software performance ceiling. Hardware instructions are required to match native speed.

Proposal

Make @node-rs/crc32 an optionalDependency and fallback to WASM when:

  • The native binding fails to load (unsupported platform, missing binary)
  • Running in environments where native modules aren't available

This gives the best of both worlds:

  • Native performance when available (~7x faster)
  • Universal compatibility via WASM fallback (works everywhere)

Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Signed-off-by: Paolo Insogna <paolo@cowtech.it>
Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina merged commit 3e0d187 into main Feb 20, 2026
19 checks passed
@mcollina mcollina deleted the wasm branch February 20, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants