[rules-users] Performace Issues drools

Welsh, Armand AWelsh at StateStreet.com
Mon Apr 23 13:09:35 EDT 2012


I will have to play with performance testing on these conditions. 

My understanding was that there is not real performance difference, because every fact insert get evaluated at insert time for rules that reference the facts, and then with exists, you are only limiting the rule to one activation for that conditional, whereas with your example, there could be multiple matches in working memory, and thus multiple activations...

In reality, it's a "not" evaluation, so they are probably identical in this case.  Either way, a performance test of large numbers of facts is definitely in my future... haha

Armand



-----Original Message-----
From: rules-users-bounces at lists.jboss.org [mailto:rules-users-bounces at lists.jboss.org] On Behalf Of Greg Barton
Sent: Monday, April 23, 2012 9:55 AM
To: Rules Users List
Subject: Re: [rules-users] Performace Issues drools

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
> 

_______________________________________________
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