tags:

views:

267

answers:

3

I am currently writing an application using Drools 5.0. This application seems to be running a little slow, but I have a theory why. This application receives many updates for facts already in stored in the knowledge session. The Drools update function under the hood really does a retraction then an insertion. This application has over 200 rules. Some of the rules are written to fire when certain facts are removed. Other rules are written to fire when certain facts are asserted into the knowledge session. Since update really does a retraction then insertion will the retraction and insertion related rules still fire during an update? Even though nothing is really being 'inserted' or retracted from the knowledge session?

One thing to note, I 'hooked' up the WorkingMemoryFileLogger to my knowledge session to get a better idea about whats going on. That's when I saw lots of unexpected retraction/insertion rule-activation creations being added to the Agenda, but it seems they don't ever get activated. It seems to me that updating facts can be expensive especially based on your fact model, and should me used sparingly. Is this correct?

A: 

The best way to know is to profile the app and find out exactly what's happening. Use something like OptimizeIt or JProbe in combination with the jvisualvm.exe that ships with JDK 1.6. Don't guess - get more data.

duffymo
I have already profiled my application. The majority of my time is consumed in the fireAllRules call that is part of the Drools interface. How that call performs is dependent on my rule design and fact model. I was hoping someone, who has a deeper understanding of the ReteOO implementation in Drools than me, could provide some insight into what exactly happens when facts are updated as opposed to asserted. Also, tell me how that could affect the fireAllRules call.
loyalBrown
A: 

I think you have understood it correctly. An update is kind of like a retract plus an assert. The first thing to be sure of is if your rules are giving you what you want - ie do it work but you just want to improve performance?

In some ways you can think of an update (and also checkout the "modify" keyword..) as part of the evils of immutability ;) When you update - you tell the network that the fact has changed, but it doesn't yet track it at a field level (that is TBD) so it may cause more work then is necessary as all these activations are created that are not really needed (as they are using fields that didn't actually change in value).

Hard to be more specific - if you provided some sample rules/fact model (if you can in a safe way of course !) we might be able to suggest some ideas to break it down to be more granular.

Good luck !

Michael Neale
Thanks for the response Micheal. You have confirmed my suspicions. The engine seems to be working correctly as far as accuracy is concerned, but my answers are latent because it takes too long to process all the rules/facts. I have some ideas for how to refactor the fact model, but wanted to verify I was focusing on the correct problem since my refactoring effort may take a while.Thanks again!
loyalBrown
A: 

In my experience, the update() method is only necessary if you need an entity to be reevaluated by the WHERE clause within the context of the currently executing rule. Since the RETE evaluation happens all at once upon entry of the rule, removing some update() statements (where possible) will speed it's execution. Sometimes this involves setting some flags and postponing the real update() until a later rule. You can also put some of the evaluation of the current entity states into an if statement in the THEN clause, using the WHERE clause for more basic filtering.

Christopher Zahrobsky