Stumbled over this today in a specific case, but my question is about a
general practice (I'm quite new to Drools, 5.2.0.M2 btw). I have a
knowledge session with a fair amount of facts (0.5 Mio) and mostly
simple rules. One rule has a LHS expression that I know will be
expensive to execute, in the example that I encountered this it looks like:
rule "Count facts"
when
all : Number() from accumulate (s : X(), count(s))
blacklisted : Number() from accumulate (s : X(status ==
X.BLACKLISTED), count(s))
....
then
....
end
I want to execute this rule only after other rules have already executed
(and changed the status of most of the X facts). There's quite a number
of X facts (~200'000). Most of them have their status modified during
execution of other rules. If I run the rule base without the above
rules, performance is perfect, some tens of seconds. If I activate the
rule, execution never finishes (I stop it after a few minutes, never saw
it finished).
I *THINK* (correct me if I'm wrong) what happens is that especially the
second expression of the LHS gets executes over and over again whenever
one of the facts is modified by one of the other rules. Makes sense, but
I nevertheless want to try to avoid it.
Until now I tried unsuccessfully:
- "protect" the rule with a guard fact as the first expression, which is
inserted only late in the processing
- move the rule to another ruleflow-group (or agenda-group) and activate
it only at the end of the processing
- use the rule in a second independent knowledge base and session, and
insert the facts once the first has finished
I'm perfectly aware that I could solve this specific problem of counting
facts with different techniques, but my question is more general (as the
subject says). Because I have other cases where (as a last resort) I
need to go to a database or online service to get the required
information. It seems that others have similar problems
(
http://drools.46999.n3.nabble.com/Short-circuiting-evaluations-on-LHS-td5...).
But in my experience, that technique ("protecting" the expensive pattern
in the LHS with a cheap one that evaluates to false until you really
need the expensive one) does not work. I get the impression that
(contrary to popular experience that a "false" value in an AND sequence
terminates the whole sequence) the drools LHS are processed differently.
Am I missing something really stupid?!
--
CU, Joe