Contribution to gnata #12
Replies: 2 comments
-
|
Hey @sandrolain, Yes, we were excited to hear the project resonated with the community, and it's equally interesting that we're not the only ones who came up with the idea of a full rewrite for production workflows. We welcome additions, but I'll preface that though this is an open-source project we do use it internally. As such, we currently prefer to do our own PRs. This will probably change eventually, but it's still very early on so we're being more strict. If you have any issues you'd like addressed (such as jsonata compatibility / performance issues), feel free to share them here. Alternatively you could contact me directly. Thanks! |
Beta Was this translation helpful? Give feedback.
-
|
Hi, I got my friend Copilot/Sonnet to work, and with a few rounds of analysis and modifications, I got the following results, in the branches of my fork, available here. Conformance fixesThe branches below fix real conformance failures. Together they raise the official test suite pass count from 1,777 to 1,784 out of 1,784 total cases (
|
| Metric | Benchmark | Baseline | After | Δ |
|---|---|---|---|---|
| sec/op | Eval/Product.SKU |
432.9 ns | 381.0 ns | −12% |
| sec/op | Eval/filter |
1.054 µs | 1.003 µs | −5% |
| sec/op | Eval/$sum |
1.415 µs | 1.344 µs | −5% |
| B/op | Eval/Product.SKU |
712 B | 584 B | −18% |
| allocs/op | Eval/Product.SKU |
10 | 8 | −20% |
| allocs/op | Eval/filter |
26 | 23 | −12% |
| geomean | sec/op | 1.771 µs | 1.745 µs | −1.45% |
| geomean | allocs/op | 43.20 | 41.83 | −3.19% |
opt/preparse-signatures
Pre-computes ParsedSig []ParamSpec on SignedBuiltin and Lambda structs at registration/closure time instead of re-running parser.ParseSig() on every function invocation. Eliminates redundant parsing inside HOF loops.
Impact: −4% geomean sec/op; −13% on Compile/Account.Name.
opt/float64-fastpath
Adds a direct float64 type-assert in binary arithmetic operators. In the common case — both operands already float64 — it skips the ToFloat64 call entirely, removing interface-dispatch overhead.
Impact: −1.5% geomean sec/op.
opt/gjson-merged-paths
When StreamEvaluator has ≥3 active fast-path expressions for the same event, resolves all GJSON paths in a single gjson.GetManyBytes scan instead of separate gjson.GetBytes calls. Deduplicates paths during buildPlan.
Impact: neutral on current benchmarks (single expression); activates in high-volume streaming workloads with ≥3 concurrent fast-path expressions.
opt/hof-args-reuse
Pre-allocates a []any buffer for $map, $filter, $single, $reduce, $sift, $each, and $sort calls, reusing it on each iteration instead of allocating a new one per element. Reduces N allocations to 1 per HOF call.
Impact: neutral on current benchmarks; significant reduction in workloads iterating over large arrays.
opt/deepequal-earlyexit
Adds a type-switch on float64/string/bool in DeepEqual before any call to normalizeNumber. In the common case (same primitive type on both sides) it bypasses normalization entirely.
Impact: −2.7% geomean sec/op; −15% on Compile/$sum.
opt/collapse-sequence-zerocopy
In CollapseSequence, transfers ownership of the Sequence.Values slice to the caller instead of cloning it defensively. Sort already clones before mutating; all other paths leave the slice unmodified. Saves one allocation per path evaluation that returns multiple values.
Impact: −10% sec/op and −18% B/op on Eval/Product.SKU; −8% sec/op on Eval/filter.
opt/cache-no-invalidate-add-remove
Removes the cache.Invalidate() call from the Add and Remove operations of StreamEvaluator. Add only appends a new expression index not present in any cached plan; Remove sets the expression to nil and evalSingleExpr already checks for nil. Only Replace and Reset still invalidate the cache.
Impact: neutral in static benchmarks; reduces lock contention in workloads with frequent dynamic expression management (Add/Remove).
Conformance — current status
| Suite | Before fixes | After fix branches |
|---|---|---|
TestSuite (local testdata) |
1790/1790 PASS | 1796/1796 PASS |
TestConformanceVsJS (live jsonata-js) |
1777/1784 PASS | 1784/1784 PASS |
The 7 fixes eliminate all remaining real failures. The function-signatures/case035–040 test cases (previously missing from testdata/) and function-split/case016–017 (expectations corrected to match the spec) are now included and passing.
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi gnata team
I'm writing through a GitHub issue since I couldn't find a more direct way to reach the maintainers — apologies if this isn't the right channel!
I've been building a JSONata-to-Go port in my spare time called gosonata (using Copilot with Claude Sonnet), but rather than maintaining a parallel fork I'd much prefer to contribute back to gnata, which already has more traction and a wider audience — meaning improvements will get better feedback and reach more users. I'm also evaluating JSONata for IoT data-pipeline work at M31, the company I work at, so having a solid and well-maintained Go implementation matters to me.
To help with the analysis I used GitHub Copilot with Claude Sonnet 4.6, running a comparative audit between gnata and gosonata cross-checked against the official JSONata 2.1 test suite.
From that work I identified some areas that could be worth evaluating together — things like closer alignment to the JSONata spec, performance improvements, and additional features. Rather than listing them all here, I'd invite you to have a look at gosonata directly, or just ask me anything — I'm happy to share details, open issues, or send PRs, whatever works best for you.
Cheers,
Sandro
Beta Was this translation helpful? Give feedback.
All reactions