string performance optimisation - #102
Conversation
267a13d to
f5a2474
比较
|
Thanks for the PR @sergeevik. Have you run some benchmarks on this? I suspect that there won't be much impact since the JVM does a lot of these optimizations already. |
|
@aeberhart Benchmarks are a complex thing. I tried them on simple examples and stumbled upon many JVM optimizations (due to the simplicity of the scenarios). This is more of a general practice (my experience). Regarding strings and creating new strings by appending to chars, the JVM might optimize them, but there's no point in waiting for JIT to notice. String appending in a loop is never optimized by JIT. Regex compilation is useful because JIT doesn't do it itself. The JVM might cache some things, but not much. |
f5a2474 to
f54cb43
比较
|
Hi @aeberhart, I removed my the String.valueOf s—they're probably pointless. I left the StringBuilder in the loop because it's still not optimized by the JIT. Also left the regex as constants. Removed the string handling in the signature calculation and reworked it to use characters (since it's essentially handling characters, but it creates extra strings). |
Third of the allocation work in #237, and the one that answers where JSONata's share of a page render actually comes from. It is not parsing — transforms are compiled once at startup and reused. It is EVALUATION: `Signature.validate` matches a function's argument signature with a regex on every invocation, allocating a `Matcher` each time, and JSONata's own coercion machinery invokes functions even for an expression with no visible call. JFR put `Pattern.matcher <- Signature.validate <- JFunction.validate <- Jsonata.validateArguments` at 36% of ALL allocation in a page render, 99.6% of the Matcher total. dashjoin/jsonata-java#102 fixes exactly this upstream, but it is open, not merged, and there is no release carrying it. Two transform shapes read a value and apply nothing to it — a bare `$state` and a single `$attr.<name>` — and those can skip JSONata entirely. They are recognised once, where the expressions are already compiled once: jsonataTrivial 766401 -> 30400 B/op (25x, ~1.28 kB -> ~50 B per eval) 191 -> 12 us/op (16x) Stringification is the SAME `Transform.asString` the JSONata path uses, not a reimplementation, so the two cannot drift on how a number, a boolean or an absent value renders. That is the whole safety argument, so it is a test rather than a claim: `TransformsSuite` compares the two over strings, empties, ints, negatives, doubles, whole doubles, a 2^53 long, booleans, JSON null, lists, objects, quotes, unicode and a missing key — with JSONata itself as the oracle. A second test pins what is NOT direct (`$attr.a.b`, `$attr."q"`, `$states`, any operator or call), because the failure mode of this growing into a second implementation of the language is worse than the allocation it saves. The benchmark fixtures deliberately use non-trivial transforms, so `page` and `pageSignals` are unchanged here. The win is per trivial SLOT, and how much a real dashboard gets depends on how many of its slots are plain `$state` — which, for `entityCard`'s value, is the common case. Claude-Session: https://claude.ai/code/session_01SD3BpUXTpWKFzNjSjrCEEa Co-authored-by: Claude Opus 5 <noreply@anthropic.com>






string and regex optimisation
For string:
For regex:
JsonParser.java
replace readEscape logic with hex data (remove create string and parse it)