Ok, it is great answer. Thanks for your help again.
Dynamic index is a good idea, but now could you give me some advice to write 
drools rules.

wangwei


The best way to explain why it was so much faster is to make an analogy
to databases. When you do:

alarmdefine(alarmreason==reason, alarmlevel!=level)

 

You are using 2 indexes, in a similar way databases does: one index
indexes alarmreason column and the other indexes alarmlevel column. The
indexing in drools is working today in the reverse order of the
declaration order. So, in the example above, first it applies alarmlevel
index, and then alarmreason index. The problem is that alarmlevel is
always 1 in you example, so drools is running over all objects, even if
the second index limits the results.
If you invert the order, the alarmreason index is applied first. As it
is more restrictive (always matches only one element), the query becomes
much faster.
So, the same way DBAs optimize queries in databases, for extreme cases
like yours (where a column has always the same value and there is a
large number of objects), the user might have to do some optimizations
when writing the rule.

Anyway, I am planning to implement some dynamic index priorization to
avoid extreme cases like that, but I'm not sure it will make drools 3.0.
Probably it will be made after it. But until there, good practices and
documentation might help. I will talk to Mark, Michael and Peter if we
can do something else before 3.0 final.

[]s
Edson


[EMAIL PROTECTED] wrote:

>Sorry, because of the time difference, I delayed to reply you. 
>I have already finished test destined by you.
>To my surprise, the result of test is very fast, it lasted only 0.6 seconds. 
>Could you tell me why? 
>
>And , you justed asked me:" do you really want to call
>  
>
>>workingMemory.fireAllRules() inside your for loop?" 
>>    
>>
>You are right, I really want to do this.
>
>This is my invoke code with drools
>
>package com.datangmobile.rules;
>
>import java.io.InputStreamReader;
>import java.io.Reader;
>
>import org.drools.RuleBase;
>import org.drools.RuleBaseFactory;
>import org.drools.WorkingMemory;
>import org.drools.compiler.PackageBuilder;
>import org.drools.rule.Package;
>
>public class alarmrules {
>
>       public static final void main(String[] args) {
>               
>               alarmrules malarmrules = new alarmrules();
>               malarmrules.startRule();
>               
>     }
>
>       void startRule()
>       {
>               try {
>                  //load up the rulebase
>            RuleBase ruleBase = readRule();
>            workingMemory = ruleBase.newWorkingMemory();
>
>            //insert alarmdefine
>            for(int i=1; i<50000; i++){
>                       
>                       alarmdefine malarmdefine = new alarmdefine();
>                       malarmdefine.setAlarmreason(i);
>                       malarmdefine.setAlarmlevel(2);
>                       malarmdefine.setObjtype(i % 4);
>                       malarmdefine.setAlarmtype(2);
>
>                       workingMemory.assertObject( malarmdefine );
>                       workingMemory.fireAllRules();
>                 }
>                                 
>            //insert alarm
>            for(int i=1; i<10000; i++)
>            {
>               alarm malarm = new alarm();
>               malarm.setAlarmreason(i);
>               malarm.setAlarmlevel(1);
>               malarm.setObjtype(i % 4);
>               malarm.setAlarmtype(2);
>               malarm.setDn("rnc=1");
>               workingMemory.assertObject( malarm );                           
>             
>                       workingMemory.fireAllRules();
>            }
>        } catch (Throwable t) {
>            t.printStackTrace();
>        }
>       }
>       
>       
>       private static RuleBase readRule() throws Exception {
>               
>               //read in the source
>               Reader source = new                     InputStreamReader( 
> alarmrules.class.getResourceAsStream( "/alarm.drl" )
>     );
>               
>               PackageBuilder builder = new PackageBuilder();
>               
>               builder.addPackageFromDrl( source );
>
>               Package pkg = builder.getPackage();
>               
>               RuleBase ruleBase = RuleBaseFactory.newRuleBase();              
>               ruleBase.addPackage( pkg );
>               
>               return ruleBase;
>       }
>       
>       private static WorkingMemory workingMemory;     
>}
>
>
>This is my invoke code with JESS:
>
>package com.datangmobile.rules;
>
>import jess.*;
>
>public class alarmrulesJess {
>
>       public static final void main(String[] args) {
>               
>               alarmrulesJess malarmrules = new alarmrulesJess();
>               malarmrules.startRule();
>               
>            }
>       
>       private void startRule(){
>               
>       try {
>                 Rete rete = new Rete();
>           rete.executeCommand("(batch alarmTest.clp)");
>            //insert alarmdefine
>            for(int i=1; i<50000; i++){
>                       
>                       alarmdefine malarmdefine = new alarmdefine();
>                       malarmdefine.setAlarmreason(i);
>                       malarmdefine.setAlarmlevel(2);
>                       malarmdefine.setObjtype(i % 4);
>                       malarmdefine.setAlarmtype(2);
>                       rete.definstance("alarmdef",malarmdefine,false);
>                       rete.run();
>                }
>            
>            //insert alarm
>            for(int i=1; i<10000; i++)
>            {
>               alarm malarm = new alarm();
>               malarm.setAlarmreason(i);
>               malarm.setAlarmlevel(1);
>               malarm.setObjtype(i % 4);
>               malarm.setAlarmtype(2);
>               malarm.setDn("rnc=1");
>               rete.definstance("alarm", malarm ,false);
>                       rete.run();
>            }                   
>            
>        } catch (Throwable t) {
>            t.printStackTrace();
>        }
>       }
>}
>
>
>
>Thanks
>wangwei
>
>
>
> Wangwei,
>
>One simple test I would like you to try is to change your rule from this:
>
>    alarmdefine(alarmreason==reason, alarmlevel!=level)
>
> To this:
>
>    alarmdefine(alarmlevel!=level, alarmreason==reason)
>
>
>Let me know if you can run the same test this way.
>
>Thank you,
>Edson
>
>
>
>Edson Tirelli 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] 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] <[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
>>>>
>>>>  
>>>>
>>>>     
>>>>
>>>>        
>>>>
>>>   
>>>
>>>      
>>>
>> 
>>
>>    
>>
>
>
>  
>

Reply via email to