Skip to content

Commit 4c6ff53

Browse files
committed
perf enhancements for logic
1 parent a473292 commit 4c6ff53

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

.jekyll-metadata

1.12 KB
Binary file not shown.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: "JSON Logic Without Models"
3+
date: 2024-04-18 09:00:00 +1200
4+
tags: [json-logic, architecture, performance]
5+
toc: true
6+
pin: false
7+
---
8+
9+
Holy performance increase, Batman!
10+
11+
I recently made an update to _JsonLogic.Net_ that cut run times and memory usage **in half**!
12+
13+
## In half?!
14+
15+
Yes! Here's the benchmark:
16+
17+
| Method | Count | Mean | Error | StdDev | Gen0 | Allocated |
18+
|------- |------ |-------------:|------------:|------------:|-----------:|------------:|
19+
| Models | 1 | 1,655.9 us | 26.76 us | 26.28 us | 410.1563 | 838.03 KB |
20+
| Nodes | 1 | 734.5 us | 8.16 us | 7.23 us | 236.3281 | 482.61 KB |
21+
| Models | 10 | 16,269.0 us | 167.06 us | 139.50 us | 4093.7500 | 8380.5 KB |
22+
| Nodes | 10 | 7,210.7 us | 25.26 us | 21.09 us | 2359.3750 | 4826.08 KB |
23+
| Models | 100 | 164,267.3 us | 2,227.54 us | 1,974.66 us | 41000.0000 | 83803.81 KB |
24+
| Nodes | 100 | 72,195.7 us | 139.28 us | 116.30 us | 23571.4286 | 48262.05 KB |
25+
26+
In this table, "Models" is the old way, and "Nodes" is the new way.
27+
28+
As you can see, "Nodes" takes less than half as long to run, and it uses just over half the memory.
29+
30+
## What do "Models" and "Nodes" represent?
31+
32+
From the initial release of the library, JSON Logic is represented using its own object model via the `Rule` abstraction. It would result in a large tree structure of strongly typed rules. This is "Models".
33+
34+
The benefit of this approach is that strong typing, meaning that if you wanted to build some logic in code, you could use the associated builder methods on the static `JsonLogic` class and you didn't have to worry about getting argument types wrong.
35+
36+
However, as you can expect, building out this rule tree means heap allocations, and allocations, in general, are slow.
37+
38+
The "Nodes" approach, introduced with v5.2.0, doesn't use the object model. Instead, the system is stateless. It uses `JsonNode` to represent the logic, and the system runs "static" handlers depending on which operation key is present. This is the approach that I took with JSON-e, and it worked out so well that I wanted to see where else I could apply it.
39+
40+
> I've had several attempts at making this approach for JSON Schema, and while it works, the performance isn't there yet.
41+
{: .prompt-info}
42+
43+
JSON-e and JSON Logic also share a common basic design: they're both JSON representations of instructions that are processed with some kind of context data.
44+
45+
## So no more strong typing?
46+
47+
I think that's where I want to take this library. With all of the soft typing and implicit conversions that JSON Logic uses anyway, I don't think it's going to be much of a problem for users.
48+
49+
Even on the [JSON Logic playground](https://jsonlogic.com/), you enter your logic and data as JSON and it runs from there. I don't see why this library can't work the same way.
50+
51+
I don't really see a reason to need an object model. (And with functional programming on the rise, maybe this stateless approach is the way of the future.)
52+
53+
But ultimately, it comes down to you. Have a play with the new setup. The [docs](https://docs.json-everything.net/logic/basics/) are already updated. I'd like to hear what you think.

0 commit comments

Comments
 (0)