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










Reply via email to