clara

eraserhd 2026-02-14T18:02:31.380619Z

Does anyone have data on Clara performance in ClojureScript? Interestingly, my current Clara project doesn't have much data, but it needs to process fire-rules < 50ms on average, on an Android tablet. I have a decent Android tablet, but I'd love to support non-decent ones.

2026-02-14T23:24:12.998969Z

I've done a lot with perf on the JVM side before but not CLJS.

2026-02-14T23:24:55.971139Z

Biggest thing there was typically using faster mutable structures in some hot spots. They were only local so didn't break the immutability observed from the outside

2026-02-14T23:25:35.648659Z

Those were mostly driven off JVM profiles hot spots in some production cases though. Had good data to use for targeting them.

2026-02-14T23:26:05.930019Z

Looking at working memory ns you'd see a lot of this I think via the read conditionals.

ethanc 2026-02-15T03:02:07.031739Z

The things that i've always struggled with when thinking about performance with clara is that no one workload will be applicable to all in most cases. Generalized performance can be considered, but a lot of the time i lean more towards pushing on the rules definition side of the equation rather than the engine itself... not to say that engine doesnt have hotspots that need to be ironed out, but more that in most cases it comes back to specific rules and data scenarios that those rules see than it does something that could be managed at a framework level.

👍 1
2026-02-15T03:16:03.779859Z

Very true. Rules can be setup with inherently problematic time/space complexity. Easy to have “Cartesian product explosions” if not careful. Often countered by using accumulators to pre filter data points before “joining to others”. On that level, it's quite similar to relational db query considerations.

eraserhd 2026-02-16T20:12:46.153579Z

Oh... I accidentally marked this thread as read before I read it...

eraserhd 2026-02-16T20:13:15.141709Z

My ClojureScript problem actually turned out to be a non-problem, the vast majority of processing was not actually Clara, and was easily removed.

eraserhd 2026-02-16T20:14:43.013389Z

However, I've attempted to make things perform better with the "salience" tag and not had much luck, but this was largely about a set of recursive rules that built a tree of data. I could come up with faster ways to process things, but "salience" wasn't a powerful enough knob.

eraserhd 2026-02-16T20:15:21.425319Z

In the case of mutual recursion, you will usually need to prioritize roots or leaves for processing, but you can only process one rule or the other.

eraserhd 2026-02-16T20:16:29.344019Z

This got me thinking about something someone said about Prolog, which was that it separates the logic from the algorithm. I've not had really that experience so much with Prolog - I've only really done toy problems - but that seems like an interesting idea.

eraserhd 2026-02-16T20:17:06.780719Z

I occasionally ponder what it would look like to have a way to prioritize leaves or roots.

eraserhd 2026-02-16T20:18:30.531469Z

(The salience bit was about a system I no longer have access to.)

2026-02-23T00:18:41.213309Z

I was never much a fan of salience as a solution. Some rare cases where there really is a logical "tiered" structure that is captured well there and I wanted to use "unconditional inserts" to seed something. If you have an example layout of your logical issues, could be cool to see to see if there is an "intermediate facts" + accumulator step approach that could be put in the middle to smooth out the dependencies and cardinality on matches downstream.

2026-02-23T00:19:24.770479Z

always a bit of an artform to this. Prolog I believe is more of a "backwards chaining" engine I believe (clara being forward chaining), which is interesting, but I don't know how to directly compare on a particular case without looking at both.

eraserhd 2026-02-14T18:02:47.062989Z

I can think of a few good work-arounds if necessary.