Skip to content

feat(python): add WASM evaluator and 3-way comparison benchmarks#73

Merged
aepfli merged 4 commits into
mainfrom
feat/python-wasm-evaluator
Feb 12, 2026
Merged

feat(python): add WASM evaluator and 3-way comparison benchmarks#73
aepfli merged 4 commits into
mainfrom
feat/python-wasm-evaluator

Conversation

@aepfli
Copy link
Copy Markdown
Contributor

@aepfli aepfli commented Feb 10, 2026

Summary

  • Add flagd_evaluator_wasm package: a Python WASM-based flag evaluator using wasmtime-py that mirrors the Go (wazero) and Java (Chicory) implementations
  • Host-side context filtering, pre-evaluated caching, and index-based evaluation — same optimization pipeline as Go/Java
  • 19 tests mirroring the existing PyO3 test suite
  • 3-way head-to-head benchmarks: PyO3 (Rust native) vs WASM (wasmtime) vs pure Python (panzi-json-logic)

Benchmark Results (8 scenarios)

Scenario PyO3 WASM Python Winner
E1: Static, empty ctx 140 ns 350 ns 250 ns PyO3
E2: Static, small ctx 240 ns 440 ns 360 ns PyO3
E3: Static, large ctx 490 ns 450 ns 370 ns Python
E4: Targeting, small ctx 140 ns 440 ns 360 ns PyO3
E5: Targeting, large ctx (110) 1.5 µs 103 µs 3.4 µs PyO3
E5b: Targeting, xlarge (1003) 1.6 µs 102 µs 3.8 µs PyO3
E6: Complex targeting, small 1.5 µs 102 µs 7.4 µs PyO3
E10: Disabled (cache) 2.2 µs 106 µs 11 µs PyO3

Key insight: wasmtime-py's per-call overhead (~100 µs) dominates, making it slower than both PyO3 and pure Python for all scenarios. The WASM approach is better suited to Go/Java where the WASM runtimes (wazero/Chicory) have lower per-call overhead.

Test plan

  • 19 WASM evaluator tests pass (pytest tests/test_wasm_evaluator.py -v)
  • 24 comparison benchmarks pass (pytest benchmarks/test_wasm_comparison.py --benchmark-only -v)
  • Existing 15 PyO3 tests unaffected
  • WASM binary must be built before running tests: cargo build --target wasm32-unknown-unknown --no-default-features --release --lib && cp target/wasm32-unknown-unknown/release/flagd_evaluator.wasm python/flagd_evaluator_wasm/

🤖 Generated with Claude Code

aepfli and others added 4 commits February 12, 2026 18:30
Add a Python WASM-based flag evaluator (wasmtime-py) that mirrors the
Go (wazero) and Java (Chicory) implementations with host-side context
filtering, pre-evaluated caching, and index-based evaluation.

- flagd_evaluator_wasm package: WasmFlagEvaluator class with same API
  as the PyO3 FlagEvaluator (evaluate, evaluate_bool/string/int/float)
- 9 host functions matching Go's host.go (time, random, wbindgen stubs)
- Pre-allocated WASM buffers (256B flag key, 1MB context)
- Context key filtering: serialize only needed keys before WASM call
- Thread-safe via threading.Lock
- 19 tests mirroring test_basic.py + test_flag_evaluation.py
- 3-way benchmarks (PyO3 vs WASM vs pure Python json-logic) across
  8 scenarios: static/targeting/disabled with empty/small/large/xlarge
  contexts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ndings

Add host-side optimizations to the PyO3 FlagEvaluator matching the WASM
and Go implementations:
- Pre-evaluated cache for static/disabled flags (skip Rust evaluation)
- Context key filtering: extract only required keys from PyDict before
  converting to serde_json::Value, avoiding full dict serialization
- evaluate_flag_pre_enriched path for pre-enriched filtered contexts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The flagd_evaluator_wasm package requires the WASM binary at runtime.
Build it from Rust source and copy to the package directory before
running tests. Also add wasm32-unknown-unknown target to Rust toolchain.

Refs: #83

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The flagd_evaluator_wasm package lives in the python/ directory as a
plain Python package. Without pythonpath configured, pytest in CI
cannot find it when running inside a uv-managed venv.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aepfli aepfli force-pushed the feat/python-wasm-evaluator branch from 52889f2 to 9991941 Compare February 12, 2026 17:34
@aepfli aepfli merged commit 3ebed59 into main Feb 12, 2026
7 checks passed
@aepfli aepfli deleted the feat/python-wasm-evaluator branch February 12, 2026 17:48
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.

1 participant