This is not at all surprising. To set up and run the rules there's quite a bit of
code running behind the scenes besides just the comparison test. (For instance,
there's object creation just to track the fact that two objects matched the rule, and
in this case those objects are created for every possible combination of TestObject
instances before the first rule ever fires, then added to lists, and so on... So in the
case of 1000 TestObject instances, there's 1,000,000 object creations and list
additions just for that.)
So, as has been said many times on this list, and probably in a few blogs, for any given
algorithm a hard coded java version will invariably be faster than rules. What rules
gives you is a way to express solutions to complex problems in a flexible and
comprehensible way. It shines when the problems are so complex that coding them
procedurally is pit of the question.
The same relationship is there between C and java. Java gives you managed, portable code,
but for that you give up the raw speed of C.
--- On Thu, 1/21/10, Tom Carchrae <carchrae(a)gmail.com> wrote:
From: Tom Carchrae <carchrae(a)gmail.com>
Subject: [rules-users] drools performance with <
To: rules-users(a)lists.jboss.org
Date: Thursday, January 21, 2010, 6:40 PM
Hello,
I'm new to Drools and am trying it out. I've found it
easy enough so
far, but quickly ran into a performance bottleneck.
(perhaps an all
too familiar story! :) ). So, I made a simple example
to try and
track down the behavior. Here it is.
I wanted to create a rule that uses an < comparison
between pairs of
objects. The following are the performance results:
10 objects. Java comparison took 0 ms
10 objects. Rule firing took 2516 ms
100 objects. Java comparison took 0 ms
100 objects. Rule firing took 1984 ms
1000 objects. Java comparison took 47 ms
1000 objects. Rule firing took 132500 ms
10000 objects. Java comparison took 4641 ms
10000 objects. Rule firing took .... (please wait...)
Here is the rule
rule "A < B"
when
a : TestObject(
)
b : TestObject(
valueDouble < a.valueDouble )
then
b.setValueint(b.getValueint()+1);
end
Now, I do understand that this (worst-case) is a comparison
of N x N
objects... so, 1000 = 1000000 comparisons. However,
~100ms per
comparison seems relatively expensive for such a simple
check. I am
using StatefulKnowledgeSession (I tried Stateless but this
gave only a
mild performance improvement - and I would also like to use
insert in
some of my rules).
How would one speed up such a query? I know part of
the problem is
the < comparison. The results with == are much
better (presumably, it
can do lots of pruning of the space)
Model creation 0
10 objects. Rule firing took 2829 ms
100 objects. Rule firing took 93 ms
1000 objects. Rule firing took 657 ms
10000 objects. Rule firing took 3375 ms
100000 objects. Rule firing took 33266 ms
I have thought about clever tricks that I could do to try
and speed
things up, like sorting into groups, etc. But it all
seems relatively
convoluted. Am I correct in coming to the conclusion
that a <
comparison is not the kind of thing that you should do in
Drools?
How would you go about this? I would prefer to keep
all the logic in
the DRL files. I'm guessing you do a Java based
comparison and use a
fire-once rule to invoke this code.
Thanks in advance for any insight,
Tom
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users