Производительность Optaplanner Drools довольно медленная - PullRequest
0 голосов
/ 22 апреля 2019

Для удобства обслуживания, удобочитаемости и простоты использования я переписал наши калькуляторы оценок в Drools и обнаружил, что он работает лишь незначительно лучше, чем наш EasyScoreCalculator и значительно медленнее, чем наш IncrementalScoreCalculator. (Основной причиной перехода на Drools является неспособность внедрить новое правило в IncrementalScoreCalculator).

Вот сравнение:

Score speed comparisons

Обратите внимание, что Drools лишь незначительно быстрее, чем Easy, и что Incremental в ~ 8-10 раз быстрее, чем любой.

У нас довольно много правил, и мы отмечаем, что, хотя некоторые правила работают примерно так же быстро или быстрее, чем пошаговые, некоторые действительно медленны и, вероятно, образуют узкое место.

Вот пример быстрого правила (~ 18-20 ккал / сек)

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

Вот пример действительно медленного правила (~ 1 Ккал / сек)

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 Ответ

1 голос
/ 23 апреля 2019

Что делает isServicable()? Вероятно, это гораздо больше, чем просто return servicable;.

Что касается второго медленного правила, это накопление на перекрестном произведении Shift и Vehicle. Накапливается немного медленно (не так медленно, как insertLogical, но все же).

Будет интересно посмотреть, как ConstraintStreams повлияет на эти показатели производительности, как только мы их выпустим.

...