Search code examples
droolsrule-engine

Accumulate/Collect vs single java loop


I have a use case in which let's say I have 100,000 pojos in the kiesession of type A and I want to apply some rules on it out of which two are -

  1. Check is a duplicate value of type A exist.
  2. sum of A.someInt is equal to the givenValue.
class A {
     private int someInt;
     private String someString;
}

For these two rules should I go with creating separate rules for them in drools like this

  1. $sumSomeInt: Integer(this > 90) from accumulate(A( $SomeInt: someInt ), sum($SomeInt))

function boolean checkDuplicate(List input) {
    int a = input.size();
    int b = ((List) input.stream().distinct().collect(Collectors.toList())).size();
    return a!=b;
}

dialect "java"
rule "ADuplicateRule"
   when
        $input : List( ) from collect(A())
        eval(checkDuplicate($input))
   then
        throw new Exception("A list has duplicate values");
end 

Or is it better to apply this in java using a single loop for this and doing both the things what I want to know is will applying these two approaches on 100k records give us a major performance difference

just a reminder I also have other rules so I have to use drools I don't want to apply some validation in java and some in drools unless there is a major performance boost


Solution

  • Drools optimizes the "when" clause. The "then", which is pure Java, is not optimized and is executed "as-is". eval statements are not optimized either and are bad practice and should be avoided at all costs. Just about anything you can do in an 'eval', you can do in a Drools native fashion.

    Given the choice, in the "when", of doing something in Java via an eval, and doing something using Drools built-in structures and methods, always prefer doing it the Drools native way. 100k records isn't very many so it probably won't be noticeable at such a scale.

    And you shouldn't be throwing exceptions -- that's also not a good practice. retract your inputs or something to force execution to terminate early.

    I shared a better way of doing duplicate detection in your other question.