Optaplanner Drools的性能相当慢

时间:2019-04-22 09:56:22

标签: drools optaplanner

出于可维护性,可读性和易用性的考虑,我将分数计算器重写为Drools,我发现它的性能仅比我们的EasyScoreCalculator好一点,但比我们的IncrementalScoreCalculator慢得多。 (切换到Drools的主要原因是无法在IncrementalScoreCalculator中实施新规则)。

这里是一个比较:

Score speed comparisons

请注意,Drools仅比Easy快一点,而Incremental则比任何一种快8-10倍。

我们有很多规则,但请注意,尽管有些规则的速度与增量速度差不多,但有些却很慢,很可能会成为瓶颈。

这是一个快速规则的示例(〜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 calcs / sec)

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


我知道这些缓慢的规则构成了瓶颈,并使整个流口水分数的计算变慢了,但是我不知道为什么这些规则是瓶颈。我唯一能想到的是,我在慢速规则中调用方法,而在快速规则中则没有。

这是为什么调用对象方法的规则要慢得多的原因吗?如果是,为什么,我该怎么办?

谢谢!

1 个答案:

答案 0 :(得分:1)

isServicable()的作用是什么?它可能做的远不止return servicable;

关于第二个慢规则,它是ShiftVehicle的叉积的累加。积累有点慢(虽然不如insertLogical慢,但仍然如此)。

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