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.
I've done a lot with perf on the JVM side before but not CLJS.
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
Those were mostly driven off JVM profiles hot spots in some production cases though. Had good data to use for targeting them.
Looking at working memory ns you'd see a lot of this I think via the read conditionals.
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.
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.
Oh... I accidentally marked this thread as read before I read it...
My ClojureScript problem actually turned out to be a non-problem, the vast majority of processing was not actually Clara, and was easily removed.
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.
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.
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.
I occasionally ponder what it would look like to have a way to prioritize leaves or roots.
(The salience bit was about a system I no longer have access to.)
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.
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.
I can think of a few good work-arounds if necessary.