Для удобства обслуживания, удобочитаемости и простоты использования я переписал наши калькуляторы оценок в Drools и обнаружил, что он работает лишь незначительно лучше, чем наш EasyScoreCalculator
и значительно медленнее, чем наш IncrementalScoreCalculator
. (Основной причиной перехода на Drools является неспособность внедрить новое правило в IncrementalScoreCalculator
).
Вот сравнение:
Обратите внимание, что 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
Я понимаю, что эти медленные правила образуют узкое место и замедляют расчет баллов слюней, но я не могу понять, почему эти правила являются узким местом. Единственное, о чем я могу думать, это то, что я вызываю метод в медленных правилах, а в быстрых - нет.
Это причина того, почему правило, вызывающее объектный метод, намного медленнее, чем в противном случае? Если да, то почему и что мне с этим делать?
Спасибо!