It is important to know the whole test case here.
Let me explain: in the snippet of code he sent us, he is doing:
malarm.setAlarmreason(i);
malarm.setAlarmlevel(1);
And in the rule, he is doing:
alarm(reason:alarmreason, level:alarmlevel)
alarmdefine(alarmreason==reason, alarmlevel!=level)
The above will create a join node with compound indexed beta memory.
This means it will not run a crossproduct between alarm and alarmdefine.
Does not matter if the guy has 1 alarm define in the WM or 1 million. It
will only try to join nodes whose alarm reason are equals and
alarmlevels are different. Thats the reason I think it is very strange
for drools to take so long to execute.
I really would like to see the full code here to understand what is
happening.
One thing that occured me is that right now, for indexing purposes,
the following two constructs are different and might have different
performance results:
1. alarmdefine(alarmreason==reason, alarmlevel!=level)
2. alarmdefine(alarmlevel!=level, alarmreason==reason)
So, I imagine the parser builds the constraint array in the order it
is written right? In case of multiple indexes, the index factory will
create each index layer wrapping the previous one. We dont have a way to
optimize this automatically tight now. So, the best way for the user to
write a rule right now is to put the most restrictive constraints in the
end of the constraint list.
As alarmreason seems to be the most constraining constraint in his
example, writing the rule as shown in case number 2 above might give a
huge boost in the peformance, but the only way I can assure is to see
the code he is using, specially how the alarmdefine's attributes are
populated.
[]s
Edson
Michael Neale wrote:
1000 x 50 000 is 50 million combinations. 5 seconds sounds reasonable
doesn't it?
On 4/26/06, *Michael Neale* < [EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
I hacked up something that looked like his (best guess) and I was
getting 5 seconds about for 50K.
fireAllRules didn't make much difference. I would like to compare
to jess
I think we need to prove that he is doing something wrong, as the
difference is just too great. I know not much about jess though.
On 4/26/06, *Edson Tirelli* < [EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
Wangwei,
Just to be sure I understood your code, do you really want to call
workingMemory.fireAllRules() inside your for loop? I assume
when you run
the same code in Jess you call "(run)" the same number of
times, right?
We know we are still slower then Jess as we have some
overheads that
Jess doesn't face (to not speak in our 6 months old compared
to Jess
years old). We, of course, are working on improving the
performance.
But, what we are seeing is, for instance, in informal
benchmarks we ran,
like Manners with 64 guests, Jess is 3 times faster. If we
raise to 128
guests, we scale better and Jess is only 2 times faster.
Also, the way you wrote the rule makes possible for Drools to
use its
indexed join optimizations, so it is the best scenario. It is
really
amazing the performance difference. If you can, would you
please send us
the whole invocation code, in a way we can run here and see
what is
being optimized and what is not? Also, it would be good to
have the jess
code, just to be sure we are comparing apples to apples.
Thanks, I do appreciate.
Edson
[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> wrote:
Thanks, the whole rule file:
package com.datangmobile.rules
import com.datangmobile.rules.alarmdefine;
import com.datangmobile.rules.alarm;
rule "alarmdefine"
no-loop true
when
#conditions
alarm(reason:alarmreason, level:alarmlevel)
alarmdefine(alarmreason==reason, alarmlevel!=level)
then
#actions
alarm.setCounter();
end
alarmdefine object:
package com.datangmobile.rules;
public class alarmdefine {
private int alarmreason;
private int alarmlevel;
private int objtype;
private int alarmtype;
public int getAlarmlevel() {
return alarmlevel;
}
public void setAlarmlevel(int alarmlevel) {
this.alarmlevel = alarmlevel;
}
public int getAlarmreason() {
return alarmreason;
}
public void setAlarmreason(int alarmreason) {
this.alarmreason = alarmreason;
}
public int getAlarmtype() {
return alarmtype;
}
public void setAlarmtype(int alarmtype) {
this.alarmtype = alarmtype;
}
public int getObjtype() {
return objtype;
}
public void setObjtype(int objtype) {
this.objtype = objtype;
}
}
alarm object:
package com.datangmobile.rules;
public class alarm {
private int alarmreason;
private int alarmlevel;
private int objtype;
private int alarmtype;
private String dn;
static private int counter = 0;
public int getAlarmlevel() {
return alarmlevel;
}
public void setAlarmlevel(int alarmlevel) {
this.alarmlevel = alarmlevel;
}
public int getAlarmreason() {
return alarmreason;
}
public void setAlarmreason(int alarmreason) {
this.alarmreason = alarmreason;
}
public int getAlarmtype() {
return alarmtype;
}
public void setAlarmtype(int alarmtype) {
this.alarmtype = alarmtype;
}
public String getDn() {
return dn;
}
public void setDn(String dn) {
this.dn = dn;
}
public int getObjtype() {
return objtype;
}
public void setObjtype(int objtype) {
this.objtype = objtype;
}
static public void setCounter(){
counter++;
}
static public int getCounter(){
return counter;
}
}
can you provide your objects that you are using, and the whole
rule file?
On 4/26/06, [EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]> <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]>> wrote:
Dear user group:
I have a queston about the performance of drools3.0.
My only one rule is:
rule "alarmdefine"
no-loop true
when
#conditions
alarm(reason:alarmreason, level:alarmlevel)
alarmdefine(alarmreason==reason, alarmlevel!=level)
then
#actions
alarm.setCounter();?
end
My eviroment: eclipse3.2M5 , jdk1.4.2-03
Testcode is :
for(int i=1; i<1000; i++)
{
alarm malarm = new alarm();
malarm.setAlarmreason(i);
malarm.setAlarmlevel(1);
malarm.setObjtype(1);
malarm.setAlarmtype(1);
workingMemory.assertObject ( malarm );
workingMemory.fireAllRules();
}
when alarmdefine exist 50000 record, execute time is 20s
when alarmdefine exist 5000 recode, execute time is 2s
Then I have done the same test with JESS, the rule is:
(defrule alarm-cleared-all
(alarm (alarmreason ?a) (alarmlevel ?x) )
(alarmdef (alarmreason ?a) (alarmlevel ?y&:(<> ?y ?x)))
=>
(call alarm setCounter)
)
when alarmdefine exist 50000 record, execute time is
only 0.2s
Great difference! Why? What can I do?
Thanks
Wangwei