Drools 比 EasyScoreCalculator [OptaPlanner] 慢得多

Drools much slower than EasyScoreCalculator [OptaPlanner]

难道 Drools 分数计算应该比 EasyScoreCalculator 更快吗?

根据我正在处理的问题大小,我注意到 Drools 比 EasyScoreCalculator 慢 2-5 倍。

例如 流口水

2019-09-04 04:53:47,681 [main] INFO  Solving started: time spent (86), best score (-306init/[0]hard/[0/0]soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
2019-09-04 04:53:50,263 [main] INFO  Construction Heuristic phase (0) ended: time spent (2671), best score ([0]hard/[9272/0]soft), score calculation speed (24149/sec), step total (306).
2019-09-04 04:54:02,592 [main] INFO  Local Search phase (1) ended: time spent (15000), best score ([0]hard/[9272/0]soft), score calculation speed (31552/sec), step total (38993).
2019-09-04 04:54:02,593 [main] INFO  Solving ended: time spent (15001), best score ([0]hard/[9272/0]soft), score calculation speed (30079/sec), phase total (2), environment mode (REPRODUCIBLE).

EasyScoreCalculator

2019-09-04 04:53:10,282 [main] INFO  Solving started: time spent (8), best score (-306init/[-306]hard/[0]soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
2019-09-04 04:53:10,972 [main] INFO  Construction Heuristic phase (0) ended: time spent (699), best score ([0]hard/[9272]soft), score calculation speed (90657/sec), step total (306).
2019-09-04 04:53:25,273 [main] INFO  Local Search phase (1) ended: time spent (15000), best score ([0]hard/[9272]soft), score calculation speed (109948/sec), step total (193419).
2019-09-04 04:53:25,273 [main] INFO  Solving ended: time spent (15000), best score ([0]hard/[9272]soft), score calculation speed (108976/sec), phase total (2), environment mode (REPRODUCIBLE).

我在本次测试中使用的唯一 Drools 规则如下:

rule "Maximise number of picked up parcels"
    when
      $job: Job(vehicle != null && vehicle.getVehicleType() != VehicleType.DUMMY)
    then
    scoreHolder.addSoftConstraintMatch(kcontext, 0, $job.getNumberOfParcels());
end

在 EasyScoreCalculator 中,它看起来像:

public void calculateScore(VehicleRoutingSolution solution) {

    int numberOfPickedUpParcels = 0;

    List<Job> jobsList = solution.getJobs();

    for (Job job : jobsList) {

      Vehicle vehicle = job.getVehicle();

      if (vehicle!= null) {
        if (VehicleType.DUMMY != vehicle.getVehicleType()) {
          numberOfPickedUpParcels += job.getNumberOfParcels();
        }

    }

    int[] constraints = new int[1];
    int[] objectives = new int[1];

    constraints[0] = 0;
    objectives[0] = numberOfPickedUpParcels;

    return BendableScore.of(constraints, objectives);
  }

这不奇怪吗?是因为我的规则效率低下,还是因为 Drools 分数计算会比简单的慢?

编辑: 这是一个很晚的编辑,但这里有一些数据来支持它。在 200、600 和 1000 大小的问题集的各种数据集上对来自 here 的 VRP 数据集进行了基准测试。虽然 EasyScoreCalculator 的性能对于较大的实例会崩溃,但它仍然比 Drools 更快。

这可能与问题中影子变量的数量有关吗?我记得当 Drools 确实优于 EasyScoreCalculator 时,运行 解决了更复杂的问题和更多的约束,但那个问题更复杂。

EDIT2: 我使用与上述相同的数据集重新 运行 实验。不知何故,Drools 现在可以更好地扩展了。不知道为什么这次没有配置更改会更快。

Drools 分数计算是递增的,因此 它比非递增的 EasyScoreCalculator 更好

但是,Drools 确实会带来性能开销,因此对于较小的数据集,这种开销可能会抵消缩放增益。使用 optaplanner-benchmark 尝试 3 个不同的数据集,每次都将大小加倍,然后查看基准报告中的性能图。