Skip to main content

Blazing Fast via Compilation

json-logic-engine has support for logic compilation which greatly enhances run-time performance of your logic. In a number of (simpler) cases, it can get rather close to native performance. Additionally, as of v2.0.0, the interpreter has an optimizer that can cache the execution plan of the logic if re-used, improving interpreted performance without the need for compilation.

Running many iterations of json-logic-js's test suite, we can observe stark performance differences between the built versions of the json-logic-engine against json-logic-js.

> node test.js
json-logic-js: 5.301s
le interpreted: 4.231s
le interpreted (optimized): 1.076s
le built: 405.174ms
le async interpreted: 3.460s
le async built: 1.625s

This comparison is not fair though, as the compilation mechanism is able to evaluate whether a particular branch is deterministic & pre-compute portions of the logic in advance. Running a different test suite that can't be pre-computed yields:

> node test.js
json-logic-js: 311.164ms
le interpreted: 209.264ms
le interpreted (optimized): 46.326ms
le built: 14.925ms
le async interpreted: 102.204ms
le async built: 53.067ms

Additionally, the compilation mechanism allows the asynchronous version of the engine to perform quite well against its interpreted counter-part.

> node perf.js & node perf2.js
interpreted: 8.132s
interpreted (optimized): 469.801ms
built: 128.023ms

Comparing the engine against an alternative library like json-rules-engine,

{
any: [{
all: [{
fact: 'gameDuration',
operator: 'equal',
value: 40
}, {
fact: 'personalFoulCount',
operator: 'greaterThanInclusive',
value: 5
}]
}, {
all: [{
fact: 'gameDuration',
operator: 'equal',
value: 48
}, {
fact: 'personalFoulCount',
operator: 'greaterThanInclusive',
value: 6
}]
}]
}

vs

{
or: [
{
and: [{
'===': [40, { val: 'gameDuration' }]
}, {
'>=': [{ val: 'personalFoulCount' }, 5]
}]
},
{
and: [{
'===': [48, { val: 'gameDuration' }]
}, {
'>=': [{ val: 'personalFoulCount' }, 6]
}]
}
]
}

The performance difference is significant:

> node rules.js
json-logic-engine: 53.452ms
json-rules-engine: 8.801s

To use this feature, you merely have to call:

const func = engine.build(logic)

And invoke func with the data you'd like to run it with.