Rust JSONLogic Expression Evaluation Slower Than JS – Looking for Code Review & Optimization Tips
From a quick look, I believe the main source of performance of the JS version is this line:
github.com/json-logic/json-logic-engine
#### compiler.js
`master`
313.
314. processing.forEach((item, x) => {
315. str = str.replace(`__%%%${x}%%%__`, item)
316. })
317.
318. const final = `(values, methods, notTraversed, asyncIterators, engine, above, coerceArray, precoerceNumber, assertSize, compareCheck) => ${buildState.asyncDetected ? 'async' : ''} (context ${buildState.extraArguments ? ',' + buildState.extraArguments : ''}) => { ${str.includes('prev') ? 'let prev;' : ''} const result = ${str}; return result }`
319. // console.log(str)
320. // console.log(final)
321. // eslint-disable-next-line no-eval
322. return Object.assign(
323. (typeof globalThis !== 'undefined' ? globalThis : global).eval(final)(values, methods, notTraversed, asyncIterators, engine, above, coerceArray, precoerceNumber, assertSize, compareCheck), {
324. [Sync]: !buildState.asyncDetected,
325. aboveDetected: typeof str === 'string' && str.includes(', above')
326. })
327. }
328.
329. export { build }
330. export { buildAsync }
331. export { buildString }
332.
333. export default {
The implementation builds a JavaScript function string from the input that implements the defined logic then evaluates that so the JS runtime gets to JIT the implementation to native code where it matters.
To beat JS here from a cold start is a _very_ tall order, it's essentially the best case for what they're optimized for; on the fly JIT what needs to be exactly as much as it needs to be and no more.
You can probably win for either sufficiently small or known ahead of time inputs by building native instructions yourself, even some very naive instructions can give orders of magnitude improvements, but of course this is not for the faint of heart.