Optaplanner Drools的表现相当缓慢

问题描述 投票:0回答:1

为了可维护性,可读性和易用性,我将我们的分数计算器重写为Drools,我发现它的表现仅略高于我们的EasyScoreCalculator,并且明显慢于我们的IncrementalScoreCalculator。 (切换到Drools的主要原因是未能在IncrementalScoreCalculator中实施新规则)。

这是一个比较:

Score speed comparisons

请注意,Drools仅略微快于Easy,而Incremental比任何一个快〜8-10倍。

我们有相当多的规则并注意到虽然有些规则与Incremental一样快或者快,但有些规则确实很慢并且可能形成瓶颈。

这是一个快速规则的例子(~18-20 k calcs / sec)

rule "The volume of all orders can't exceed the volume of the van"
    when $vehicle : Vehicle($capacity : capacity)
      accumulate(
        Customer(
          vehicle == $vehicle,
          $demand : demand);
        $demandTotal: sum($demand);
        $demandTotal > $capacity
      )
    then
      scoreHolder.addHardConstraintMatch(kcontext, 2, -Math.round($demandTotal - $capacity));
end

这是一个非常慢的规则的例子(约1k计算/秒)

rule "A shipment cannot be serviced outside of the shift's service hours"
  when
    $c: TimeWindowedCustomer( vehicle != null, this.isServicable() == true);
  then
    scoreHolder.addHardConstraintMatch(kcontext, 0, -1);
end

另一个非常慢的规则的例子:

rule "Total used volume in future shifts"
  when
    $shift: Shift(isCurrent() == false)
    $vehicle: TimeWindowedVehicle($shift == shift, $capacity: capacity)
    accumulate(
      Customer(
         vehicle == $vehicle,
         $demand : demand);
      $demandTotal: sum($demand);
      $demandTotal > 0
    )
  then
    int utilisedFutureShiftVolumePenalty = Params.App.Solver.Scoring.utilisedFutureShiftVolumePenalty;
    long score = - utilisedFutureShiftVolumePenalty * Math.round($demandTotal);
    scoreHolder.addSoftConstraintMatch(kcontext, 1, score);
end


我知道这些缓慢的规则形成了一个瓶颈,并且减缓了整个流氓计分的计算速度,但我无法弄清楚为什么这些规则是瓶颈。我唯一能想到的是,我在缓慢的规则中调用一种方法,而在快速的规则中,我没有。

这是一个原因,为什么调用对象方法的规则要慢得多?如果是,为什么以及我该怎么做呢?

谢谢!

drools optaplanner
1个回答
1
投票

isServicable()做什么?它可能远远超过return servicable;

至于第二个缓慢的规则,它是ShiftVehicle的交叉积累。积累有点慢(不像insertLogical那么慢,但仍然)。

一旦我们发布它们,看看ConstraintStreams如何影响这些性能基准将会很有趣。

© www.soinside.com 2019 - 2024. All rights reserved.