Narrowed Scope
This issue was originally a broad exploration of Java 21-25 features (FFM, Vector API, Compact Headers, Shenandoah, Stable Values). Based on the current state of jjq, the scope has been narrowed to zero-code-change JVM flag experiments and one future API item.
Removed from scope
| Feature |
Reason |
| FFM off-heap tape storage |
Depends on #6 (tape format) which is closed. Off-heap storage adds lifecycle complexity incompatible with jjq's zero-dependency philosophy. |
| FFM for native simdjson |
Adds native library dependency, requires platform-specific builds. jjq's pure-Java parser at 170% of Jackson is fast enough. |
| Vector API (JEP 508) |
Still incubating after 10 rounds. SWAR in SwarUtil already covers the high-impact case (string scanning). Not worth the API instability risk. |
Remaining items
1. Compact Object Headers (JEP 519, JDK 25) — zero code change
Run the full benchmark suite with -XX:+UseCompactObjectHeaders. With jjq's small wrapper objects (JqNull=16B, JqBoolean=16B, JqNumber=40B, JqString=32B), the 4-8 byte header reduction is proportionally significant. Others report ~10% on JSON parsing workloads.
2. GC collector comparison — zero code change
Compare on sustained jjq workloads (e.g., h5m upload processing):
- G1 (default)
- Generational Shenandoah (
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational)
- ZGC (
-XX:+UseZGC)
jjq's allocation pattern (many short-lived value objects during query evaluation) is textbook young-gen GC workload. Measure throughput and pause times.
3. Stable Values (JEP 502) — park until JDK 26
When Stable Values becomes final (likely JDK 26), evaluate replacing:
ThreadLocal<StringBuilder> serialization buffer in JqValues
ThreadLocal<VirtualMachine> in JqProgram (if still ThreadLocal-based)
JqNumber.cachedDecimal lazy field
The knowledge tree hypothesis says "ThreadLocal VM lookup will become dominant overhead as other hotspots are resolved" — Stable Values would address this.
Deliverables
- Benchmark results comparing JVM flags on the existing benchmark suite
- Recommended JVM flags for jjq/h5m deployments
- Go/no-go for each remaining item
Narrowed Scope
This issue was originally a broad exploration of Java 21-25 features (FFM, Vector API, Compact Headers, Shenandoah, Stable Values). Based on the current state of jjq, the scope has been narrowed to zero-code-change JVM flag experiments and one future API item.
Removed from scope
SwarUtilalready covers the high-impact case (string scanning). Not worth the API instability risk.Remaining items
1. Compact Object Headers (JEP 519, JDK 25) — zero code change
Run the full benchmark suite with
-XX:+UseCompactObjectHeaders. With jjq's small wrapper objects (JqNull=16B, JqBoolean=16B, JqNumber=40B, JqString=32B), the 4-8 byte header reduction is proportionally significant. Others report ~10% on JSON parsing workloads.2. GC collector comparison — zero code change
Compare on sustained jjq workloads (e.g., h5m upload processing):
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational)-XX:+UseZGC)jjq's allocation pattern (many short-lived value objects during query evaluation) is textbook young-gen GC workload. Measure throughput and pause times.
3. Stable Values (JEP 502) — park until JDK 26
When Stable Values becomes final (likely JDK 26), evaluate replacing:
ThreadLocal<StringBuilder>serialization buffer inJqValuesThreadLocal<VirtualMachine>inJqProgram(if still ThreadLocal-based)JqNumber.cachedDecimallazy fieldThe knowledge tree hypothesis says "ThreadLocal VM lookup will become dominant overhead as other hotspots are resolved" — Stable Values would address this.
Deliverables