[rules-users] Performace Issues drools

Greg Barton greg_barton at yahoo.com
Mon Apr 23 12:55:18 EDT 2012


You can simplify the last condition to:

not LabTest(testId == $test.testId)

I think it's faster, too.

--- On Mon, 4/23/12, Welsh, Armand <AWelsh at statestreet.com> wrote:

> From: Welsh, Armand <AWelsh at statestreet.com>
> Subject: Re: [rules-users] Performace Issues drools
> To: "'Rules Users List'" <rules-users at lists.jboss.org>
> Date: Monday, April 23, 2012, 11:13 AM
> I don't know your data model, but I
> believe, what you may be looking for is;
> 
>  CONDITION:
>     $pt: Patient ( )
>     $test : LabTest( ) from $pt.labTests
>     not (exists (LabTest (testId ==
> $test.testId)))
>  CONSEQUENCE
>     Insert($test);
> 
> 
> If I am recalling this correctly, line2 does not inject
> anything into working memory yet, and the only reference in
> memory to the collection of tests for the patent is
> $test.  Whereas Line 3 uses the Rete indexed items that
> were inserted into working memory, so what you are
> effectively doing, is blocking the fact from being inserted
> twice, because one it is inserted, it is indexed, and
> associated with the rules where it is uses, and since this
> rule states it must not exist, this rule cannot fire again,
> since it can only be activated when there is no matching
> labTest.
> 
> However, the test should not be inserted more than once,
> because it should only fire for changes, not the whole list
> every time.  To trigger a change on the original
> version of the rule, you would have to change the Patient
> record to trigger a reactivation of the rule.
> 
> In this modified version of the rule, any change to LabTest
> or Patient would trigger a reactivation of the rule, so the
> original version may be the better rule, since it involves
> less work to evaluate the activation triggers (only
> slightly, but less is less).
> 
> -----Original Message-----
> From: rules-users-bounces at lists.jboss.org
> [mailto:rules-users-bounces at lists.jboss.org]
> On Behalf Of Pedro Loaiza
> Sent: Monday, April 23, 2012 4:59 AM
> To: Rules Users List
> Cc: rules-users at lists.jboss.org
> Subject: Re: [rules-users] Performace Issues drools
> 
> I want implement this.  How would you control the
> insertion rule in order to avoid having it insert duplicates
> or re-fire?
> 
> Thanks
> 
> On Apr 19, 2012, at 10:56 AM, "Welsh, Armand" <AWelsh at statestreet.com>
> wrote:
> 
> > This may no longer be the case, but my understanding is
> that when you use from to query data from a member list of
> another object in working memory, that those members are not
> indexed by Rete.
> > 
> > I think every time the rule evaluates, it has to
> iterate through the entire member list (collection) to find
> the matching facts that are extracted for additional
> evaluation.
> > 
> > With that said, if you have one rule that extracts the
> facts, and inserts them into working memory, they will be
> indexed and now many operations on the fact type will be
> pre-computed at the time of insert, improving performance
> dramatically.  I don't know if this makes sense, but
> consider the following:
> > 
> > 
> > CONDITION:
> >    $pt: Patient ( )
> >    LabTest( ) from $pt.labTests
> >    $numTests: Number ( ) from accumulate
> (  LabTest($type: type == "lab"), count($type) )
> > 
> > Drools first collects all the Patient facts and for
> each Patient it extracts the collections of tests.  Now
> the collection of patients are already known by Rete, so
> this has been pre-computed at time of fact insert.
> > Next, for each Patient fact, drools extracts the
> collection of LabTests performed. These are not indexed by
> Rete to they are not actually in working memory.  Each
> time this rule is evaluated, the collection of LabTests must
> be generated.
> > Next the accumulate evaluates the LabTest facts to find
> those that have a getType() == "lab".  Since the facts
> do not exist in working memory, accumulate iterates all the
> LabTest fact and extracts just the ones where getType ==
> "lab".  If the rule file 10 times, that's 10 iterations
> of the collection.
> > 
> > If you break this into two rules:
> > 
> > CONDITION:
> >    $pt: Patient ( )
> >    $test : LabTest( ) from $pt.labTests
> > CONSEQUENCE
> >    Insert($test);
> > 
> > CONDITION:
> >    $numTests: Number ( ) from accumulate
> (  LabTest($type: type == "lab"), count($type) )
> > 
> > 
> > In this scenario, Drools only extracts the LabTest
> facts once, and inserts them in working memory, so that when
> the 2nd rule is evaluated, it is already known which LabTest
> facts are in memory that exist, and the iteration only
> happened once, at insert time, instead at every rule
> evaluation.
> > 
> > My understanding may be obsolete, and inaccurate as it
> applies to Drools 5.4, but this is the type of coding
> changes I have made in the past to improve
> performance.  The key is knowing how to control the
> insertion rule, so it does not insert duplicates, or refire
> unexpectedly.
> > 
> > Care must be taken to ensure you are properly binding
> your facts when you do this though... But the most speed
> benefit in drools comes from using the rete engine to avoid
> multiple iterations of the same collection...
> > 
> > -----Original Message-----
> > From: rules-users-bounces at lists.jboss.org
> [mailto:rules-users-bounces at lists.jboss.org]
> On Behalf Of sanal
> > Sent: Tuesday, April 17, 2012 4:27 AM
> > To: rules-users at lists.jboss.org
> > Subject: Re: [rules-users] Performace Issues drools
> > 
> > Hi,
> > Still Iam facing some issues with the accumulte.Please
> see the below
> > senario.I am trying to explain with the below example.
> > 
> > 
> > 
> > 
> > Suppose Glucose is a OrderedComponent which is under
> Labgroup.
> > 
> > 
> > 
> > PackageComponent(Rule)
> > 
> > ------------------------------
> > LABGroup (ComponentKey=100)       
>            qtyLimit(2)
> > 
> > 
> > OrderedComponent
> > 
> > -------------------------------
> > Order1   Glucose
> (ComponentKey=101)       Ordered
> qty (1)           
> > ParentKey(100), ParentKey(4)
> > Order2   Glucose
> (ComponentKey=101)       Ordered
> qty (1)           
> > ParentKey(100) ,ParentKey(4)
> > Order3   Glucose
> (ComponentKey=101)       Ordered
> qty (1)           
> > ParentKey(100), ParentKey(4)
> > 
> > 
> > 
> > Rule execution flow which i require.
> > 
> > 
> > 
> > 1) I need to check any rule exist for
> Orderedcomponent.If exist Execute the
> > Rule.
> > 
> >   In this case no rule exist for
> glucose.
> > 
> > 
> > 
> > 
> > 
> > 2) If no rule is found for the Orderedcomponent.I need
> to Check if any rule
> > exist for its parent(group).
> >   I am trying to achive this by changing
> the component key. The component
> > key is changed to that of 
> >   the parent and the rules are executed
> once again.This process is
> > contiuned until any rules exist for the group
> > 
> >  or root parent is reached(tree format).
> > 
> > 
> > 
> > 
> > 
> >   1st Issue
> >   Here  parent of glucose is Lab.
> And Lab has got rule.So the Parent rule
> > of lab should get executed.
> >   In this senario only 2 glucose orders
> should go under package. 3rd one
> > should not go under package.
> >   With my existing Drl all the 3 are
> going inside the package.How can i
> > correct this?
> > 
> >   2nd Issue
> >   While accumulating with lab group,all
> ordered items whose parent group is
> > lab should be summed up.
> > 
> > 
> >   The salience is used in such a manner
> because i need to execute the rules
> > for the services first
> >   and later the rules for its parents
> group.
> > 
> > 
> > 
> >   Please find the modified drl as per
> your suggestion.
> > 
> > 
> > 
> > 
> > 
> > package com.his.billing.domain;
> > 
> > import com.his.clinical.domain.PackageDefinition;
> > import com.his.clinical.domain.PackageComponent;
> > import com.his.billing.domain.OrderedComponent;
> > import com.his.billing.domain.AccumulatedComponent;
> > 
> > 
> > /*#From row number: 12*/
> > rule "Check whether is  orderedComponent is
> excluded"
> > 
> > salience 7
> > when
> >  $objOrderedComponents:AccumulatedComponent()
> > 
> > 
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
> > and
> > 
> >
> $pkgComps:PackageComponent(componentKey==$id1,isExcluded==true,(tariffClassTypeValue==null
> > || tariffClassTypeValue=="" ||
> (tariffClassTypeValue!=null &&
> > tariffClassTypeValue ==
> $orderTariffClassType)),(tariffClassValue==null ||
> > (tariffClassValue!=null &&
> >
> tariffClassValue==$orderTariffClassId)),isPackageComponent==true,isActive==true)
> 
> > then
> >  $orderedComponent.setIsExluded(true);
> > 
>>    $orderedComponent.setIsPackageComponent(true);
> 
> >     end
> > /*#From row number: 21*/
> > rule "Check whether is  orderedComponent quantity
> limit exceeded"
> > 
> > salience 6
> > when
> >  $objOrderedComponents:AccumulatedComponent()
>> $packageDefinition:PackageDefinition($packageId:packageId)
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
> > and
> >  $accumulatedQty:Number()
> >     from accumulate (
> >
> $accQtyComponent:OrderedComponent(packageChargeRecordId==$packageId,
> $AccQty
> > : componentQty) from
> >
> $objOrderedComponents.getOrderedComponentList(),sum($AccQty
> ) )  and
>> $pkgComps:PackageComponent(componentKey==$id1,(quantityLmt
> == 0 ||
> > quantityLmt != null ||  quantityLmt
> >
> <($qty+$accumulatedQty.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
> > || tariffClassTypeValue=="" ||
> (tariffClassTypeValue!=null &&
> > tariffClassTypeValue ==
> $orderTariffClassType)),(tariffClassValue==null ||
> > (tariffClassValue!=null &&
> tariffClassValue==$orderTariffClassId))) 
> > then
> >   $orderedComponent.setIsQtyExceeded(true);
> 
> > 
> >       
> $orderedComponent.setIsPackageComponent(true); 
> > end
> > /*#From row number: 21*/
> > rule "Check whether is  orderedComponent Amount
> limit exceeded"
> > 
> > salience 5
> > when
> >  $objOrderedComponents:AccumulatedComponent()
>> $packageDefinition:PackageDefinition($packageId:packageId)
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
> > and
> >  $accumulatedAmount:Number()
> >     from accumulate (
> >
> $accAmtComponent:OrderedComponent(packageChargeRecordId==$packageId,$accAmount:componentAmt)
> > from
> $objOrderedComponents.getOrderedComponentList(),sum($accAmount
> ) )  and
> >  $pkgComps:PackageComponent(componentKey==$id1,(
> amountLmt == 0 ||
> > amountLmt == null || amountLmt
> >
> <($amount+$accumulatedAmount.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
> > || tariffClassTypeValue=="" ||
> (tariffClassTypeValue!=null &&
> > tariffClassTypeValue ==
> $orderTariffClassType)),(tariffClassValue==null ||
> > (tariffClassValue!=null &&
> tariffClassValue==$orderTariffClassId))) 
> > then
> >   $orderedComponent.setIsAmtExceeded(true);
> 
> > 
> >   $orderedComponent.setIsPackageComponent(true);
> 
> > end
> > 
> > /*#From row number: 22*/
> > rule "Check whether is  orderedComponent is
> exempted"
> > 
> > salience 4
> > when
>>    $objOrderedComponents:AccumulatedComponent()
> > 
> > 
>> $orderedComponent:OrderedComponent($id1:componentKey)
> > 
> >
> $pkgComps:PackageComponent(componentKey==$id1,isPackageComponent==true,exemption==true,isActive==true)
> >    then
> >  $orderedComponent.setExemption(true); 
> > 
> >  $orderedComponent.setIsPackageComponent(true); 
> > end
> > /*#From row number: 21*/
> > rule "Check whether orderedComponent satisfy all
> rules.Then assign package
> > id"
> > 
> > salience 3
> > when
>>    $objOrderedComponents:AccumulatedComponent()
>> $packageDefinition:PackageDefinition($packageId:packageId)
> > 
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,packageChargeRecordId!=$packageId,$amount:componentAmt,$qty:componentQty,$orderTariffClassType:tariffClassType,$orderTariffClassId:tariffClassValue)
> > and
> > 
> >     $accumulatedAmount:Number()
> >     from accumulate (
> >
> $accAmtComponent:OrderedComponent(packageChargeRecordId==$packageId,$accAmount:componentAmt)
> > from
> $objOrderedComponents.getOrderedComponentList(),sum($accAmount
> ) )  and
> >     $accumulatedQty:Number()
> >     from accumulate (
> >
> $accQtyComponent:OrderedComponent(packageChargeRecordId==$packageId,
> $AccQty
> > : componentQty) from
> >
> $objOrderedComponents.getOrderedComponentList(),sum($AccQty
> ) )  and
>> $pkgComps:PackageComponent(componentKey==$id1,isExcluded==false,(amountLmt
> > == 0 || amountLmt == null || amountLmt
> >> =($amount+$accumulatedAmount.intValue())),(
> quantityLmt ==0 || quantityLmt
> > ==null || quantityLmt
> >>
> =($qty+$accumulatedQty.intValue())),isPackageComponent==true,isActive==true,(tariffClassTypeValue==null
> > || tariffClassTypeValue=="" ||
> (tariffClassTypeValue!=null &&
> > tariffClassTypeValue ==
> $orderTariffClassType)),(tariffClassValue==null ||
> > (tariffClassValue!=null &&
> tariffClassValue==$orderTariffClassId))) from
> > $packageDefinition.getPackageComponentList()
> > then
> >   $orderedComponent.setIsComponentApplicable(true);
> >       
> $orderedComponent.setPackageChargeRecordId($packageId); 
> 
> > 
> >       
> $orderedComponent.setIsPackageComponent(true);
> >        modify($orderedComponent){};
> 
> >  modify($objOrderedComponents){};
> > end
> > 
> > 
> > /*#From row number: 22*/
> > rule "If no rule exist for orderedComponent Check
> whether orderedComponent
> > is a pharmacy item then assign its generic naame and
> then apply the rules"
> > 
> > salience 2
> > when
>>    $objOrderedComponents:AccumulatedComponent()
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,isPackageComponent==false,componentType=="1052374",haveReachedRootNode==false)
> >    then
> >       
> $orderedComponent.setGenericComponentKey();
> > 
> >       
> modify($orderedComponent){};
> >       
> modify($objOrderedComponents){};
> > 
> > end
> > /*#From row number: 22*/
> > 
> > rule "If no rule exist for orderedComponent Check
> whether  rule exist for
> > its parent group"
> > 
> > salience 1
> > when
>>    $objOrderedComponents:AccumulatedComponent()
> > 
> >
> $orderedComponent:OrderedComponent($id1:componentKey,isPackageComponent==false,haveReachedRootNode==false)
> >    then
> >       
> $orderedComponent.setGroupComponentKey();
> > 
> >  modify($orderedComponent){};
> >       
> modify($objOrderedComponents){};
> > end
> > 
> > 
> > Regards
> > Sanal.P
> > 
> > --
> > View this message in context: http://drools.46999.n3.nabble.com/Performace-Issues-drools-tp3902270p3916971.html
> > Sent from the Drools: User forum mailing list archive
> at Nabble.com.
> > _______________________________________________
> > rules-users mailing list
> > rules-users at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> > 
> > _______________________________________________
> > rules-users mailing list
> > rules-users at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> 
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
> 
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
> 



More information about the rules-users mailing list