-
Notifications
You must be signed in to change notification settings - Fork 479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow performance while having large array of facts. #324
Comments
@jyothis-qb Any solution for speeding up Performance ? |
@mjaniko @jyothis-qb I would need to see the actual rules to get a sense for exactly the cause. However I can say that if you're using JSON path expressions to turn an array of 80,000 objects into an array of 80,000 values then it's going to be slow. Generally you may be better off trying to flatten/ normalize the data so there are no path expressions to evaluate. |
I'm also facing the same issue but mine is a simple object, but array of object is huge. but the object itself doesn't have a nested path. was there any resolution on this? |
@JeffrinCh Again I would need to see a specific example to understand exactly but if you're using the |
@jyothis-qb @JeffrinCh I did some digging and here's my suggestions: In order to speed up your access you could create dynamic facts: engine.addFact(
new Fact('factCol1', async (_, almanac) => {
const f = await almanac.factValue('fact');
return f.col1;
});
) If you're doing lots of path access you could simplify this by creating single facts and using parameters engine.addFact(
new Fact('factCol', async ({ col }, almanac => {
const f = await almanac.factValue('fact');
return f[`col${col}`];
})
);
// access your fact with
{
"fact": "factCol",
"params": { col: 1 }
...
} This provides a slightly improved performance over using the path value but not quite the same performance benefit of having a specific dynamic fact. |
json-path requires a decent amount of overhead; it's a relatively complex spec. I'm not surprised that using the Its my belief that the underlying json-path library we use (jsonpath-plus) is well optimized for performance, however if there is a performance improvement to be made, it will reside in that library. I agree with the workaround above of using dynamic facts in place of json-path. |
@CacheControl I also did some digging / profiling of jsonpath-plus and it does seem to be very very optimized. It already caches the results of compiling a path into a function so repeated uses of the same path will not cause re-compilation. The performance is so optimized that even without the caching the behavior is only slightly abnormal. Suggesting this could probably be closed with Dynamic Facts being the solution. |
Will try these and check |
hi @CacheControl @chris-pardy @JeffrinCh , We are using json-rule-engine in our project to get outcome by evaluating around 10k records stored in mongodb. { "conditions": { "all": [ { "fact": "customer_delivery_address", "operator": "equal", "factLabel": "Customer Delivery Address", "value": "GB", "valueSet": [ { "value": "GB", "label": "GB" } ] }, { "fact": "customer_tier", "operator": "equal", "factLabel": "Customer Tier", "value": "gold", "valueSet": [ { "value": "gold", "label": "Gold" } ] }, { "fact": "new_customer", "operator": "isBoolean", "factLabel": "New Customer", "value": true, "valueSet": [ { "value": true, "label": true } ] }, { "fact": "order_amount", "operator": "greaterThan", "factLabel": "Order Amount", "value": 2500, "valueSet": [ { "value": 2500, "label": "2500" } ] }, { "fact": "order_count", "operator": "lessThan", "factLabel": "Order Count", "value": 100, "valueSet": [ { "value": 100, "label": "100" } ] }, { "fact": "order_date", "operator": "isDateGreaterThan", "factLabel": "Order Date", "value": "2024-02-01T05:15:44Z", "valueSet": [ { "value": "2024-02-01T05:15:44Z", "label": "2024-02-01T05:15:44Z" } ] }, { "fact": "order_date", "operator": "isDateLessThan", "factLabel": "Order Date", "value": "2024-03-01T05:10:50Z", "valueSet": [ { "value": "2024-03-01T05:10:50Z", "label": "2024-03-01T05:10:50Z" } ] }, { "fact": "order_state", "operator": "equal", "factLabel": "Order State", "value": "confirmed", "valueSet": [ { "value": "confirmed", "label": "Confirmed" } ] }, { "fact": "payment_state", "operator": "equal", "factLabel": "Payment State", "value": "paid", "valueSet": [ { "value": "paid", "label": "Paid" } ] }, { "fact": "customers", "operator": "equal", "factLabel": "Customers", "value": "[email protected]", "valueSet": [ { "value": "[email protected]", "label": "[email protected]" } ] } ] }, "event": { "type": "categories", "params": { "label": "Category", "value": "Fitness Kit", "key": "8173dfd1-d8a1-417d-ab78-07dfa6799f59", "operator": "is", "source": "resource" } } } Can you please help me understand why it is taking so much time to evaluate this type of rule. If possible please share solutions for improving performance also. |
I have integrated json-rules-engine with a project I am working on and the performance seems much slower than I would expect. I'm using the package to do a simple lookup at another set of facts.
In my case, the lookupfacts array seems to contain about 80000 entries and it takes around 30000 ms to complete. Whereas doing the same comparison using simple javascript code takes about 10-15 ms only.
I will only be not be having any dynamic data in the flow. Is there a way to improve performance?
Thanks
The text was updated successfully, but these errors were encountered: