【问题标题】:Accumulate/Collect vs single java loop累积/收集与单个 java 循环
【发布时间】:2021-09-30 17:35:07
【问题描述】:

我有一个用例,假设我在 A 类型的 kiesession 中有 100,000 个 pojo,我想对其应用一些规则,其中两个是 -

  1. 检查是否存在类型 A 的重复值。
  2. A.someInt 的总和等于给定值。
class A {
     private int someInt;
     private String someString;
}

对于这两个规则,我应该像这样在流口水中为它们创建单独的规则

  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 

或者在java中使用单个循环来应用它并做这两个事情我想知道的是在100k记录上应用这两种方法会给我们带来很大的性能差异

只是提醒一下,我还有其他规则,所以我必须使用 drools 我不想在 java 中应用一些验证,在 drools 中应用一些验证,除非有显着的性能提升

【问题讨论】:

    标签: drools rule-engine


    【解决方案1】:

    Drools 优化了“when”子句。纯 Java 的“then”未优化并“按原样”执行。 eval 语句也没有优化,是不好的做法,应该不惜一切代价避免。几乎任何你可以在“评估”中做的事情,你都可以用 Drools 原生方式来做。

    在“何时”选择通过eval 在 Java 中做某事,并使用 Drools 内置结构和方法做某事时,总是更喜欢以 Drools 原生方式来做。 10 万条记录并不是很多,因此在这样的规模下可能不会引起注意。

    而且您不应该抛出异常——这也不是一个好习惯。 retract您的输入或强制执行提前终止的东西。

    我在您的 other question 中分享了一种更好的重复检测方法。

    【讨论】:

    • 您好,感谢您的回答,您能否提供更多详细信息,说明为什么我不应该在 drl 的“then”中抛出异常?
    • 还有一个问题,所以你说 10 万条记录并不是很多,正如我所提到的,我还有大约 15 条其他基本规则[它们对字段进行空检查和格式验证] 适用于单个 pojo根据您的经验,只有这两条规则我需要应用在所有 A 类型的 pojo 上我在哪里执行[仅供参考,在我的情况下它将是 lambda],但你能给出一些估计,比如它会在几秒钟内还是几分钟内
    • 例外,您正在强制drools引擎异常终止。无论如何,您都不会从中获得清晰的堆栈跟踪,那么为什么不更优雅地终止处理呢?
    • 内存中 10 与 100(或 1000 或 10k 或...)对象的影响归结为这些对象是什么、它们的大小以及它们序列化的干净程度。很难衡量“时间”,因为它取决于您的对象有多复杂以及您的规则执行的操作有多复杂。我们可以笼统地描述这一点(例如O(n)),但它也将归结为流口水的生命周期——即“匹配”阶段以及根据工作记忆的变化你重新进入这个阶段的次数。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    相关资源
    最近更新 更多