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(a)lists.jboss.org [mailto:rules-users-bounces@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(a)statestreet.com> wrote:
From: Welsh, Armand <AWelsh(a)statestreet.com>
Subject: Re: [rules-users] Performace Issues drools
To: "'Rules Users List'" <rules-users(a)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(a)lists.jboss.org
[mailto:rules-users-bounces@lists.jboss.org]
On Behalf Of Pedro Loaiza
Sent: Monday, April 23, 2012 4:59 AM
To: Rules Users List
Cc: rules-users(a)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(a)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(a)lists.jboss.org
[mailto:rules-users-bounces@lists.jboss.org]
On Behalf Of sanal
> Sent: Tuesday, April 17, 2012 4:27 AM
> To: rules-users(a)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-tp3902270p3916...
> Sent from the Drools: User forum mailing list archive
at
Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org