JBoss.orgCommunity Documentation

Chapter 9. Benchmarking and tweaking

9.1. Finding the best configuration
9.2. Building a Benchmarker
9.2.1. Building a basic Benchmarker
9.2.2. Warming up the hotspot compiler
9.3. Summary statistics
9.3.1. Best score summary
9.4. Statistics per data set (graph and CSV)
9.4.1. Best score over time statistic (graph and CSV)
9.4.2. Calculate count per second statistic (graph and CSV)
9.4.3. Memory use statistic (graph and CSV)

Drools Planner supports several solver types, but you're probably wondering which is the best one? Although some solver types generally perform better then others, it really depends on your problem domain. Most solver types also have settings which can be tweaked. Those settings can influence the results of a solver a lot, although most settings perform pretty good out-of-the-box.

Luckily, Drools Planner includes a benchmarker, which allows you to play out different solver types and different settings against each other, so you can pick the best configuration for your problem domain.

You can build a Benchmarker instance with theXmlSolverBenchmarker. Configure it with a benchmarker configuration xml file:

    XmlSolverBenchmarker benchmarker = new XmlSolverBenchmarker();

    benchmarker.configure("/org/drools/planner/examples/nqueens/benchmark/nqueensSolverBenchmarkConfig.xml");
    benchmarker.benchmark();
    benchmarker.writeResults(resultFile);

A basic benchmarker configuration file looks something like this:


<?xml version="1.0" encoding="UTF-8"?>
<solverBenchmarkSuite>
  <benchmarkDirectory>local/data/nqueens</benchmarkDirectory>
  <solverStatisticType>BEST_SOLUTION_CHANGED</solverStatisticType>
  <warmUpSecondsSpend>30</warmUpSecondsSpend>

  <inheritedSolverBenchmark>
    <unsolvedSolutionFile>data/nqueens/unsolved/unsolvedNQueens32.xml</unsolvedSolutionFile>
    <unsolvedSolutionFile>data/nqueens/unsolved/unsolvedNQueens64.xml</unsolvedSolutionFile>
    <solver>
      <solutionClass>org.drools.planner.examples.nqueens.domain.NQueens</solutionClass>
      <planningEntityClass>org.drools.planner.examples.nqueens.domain.Queen</planningEntityClass>
      <scoreDrl>/org/drools/planner/examples/nqueens/solver/nQueensScoreRules.drl</scoreDrl>
      <scoreDefinition>
        <scoreDefinitionType>SIMPLE</scoreDefinitionType>
      </scoreDefinition>
      <termination>
        <maximumSecondsSpend>20</maximumSecondsSpend>
      </termination>
    </solver>
  </inheritedSolverBenchmark>

  <solverBenchmark>
    <name>Solution tabu</name>
    <solver>
      <localSearch>
        <selector>
          <moveFactoryClass>org.drools.planner.examples.nqueens.solver.move.factory.NQueensMoveFactory</moveFactoryClass>
        </selector>
        <acceptor>
          <completeSolutionTabuSize>1000</completeSolutionTabuSize>
        </acceptor>
        <forager>
          <pickEarlyType>NEVER</pickEarlyType>
        </forager>
      </localSearch>
    </solver>
  </solverBenchmark>
  <solverBenchmark>
    <name>Move tabu</name>
    <solver>
      <localSearch>
        <selector>
          <moveFactoryClass>org.drools.planner.examples.nqueens.solver.move.factory.NQueensMoveFactory</moveFactoryClass>
        </selector>
        <acceptor>
          <completeMoveTabuSize>5</completeMoveTabuSize>
        </acceptor>
        <forager>
          <pickEarlyType>NEVER</pickEarlyType>
        </forager>
      </localSearch>
    </solver>
  </solverBenchmark>
  <solverBenchmark>
    <name>Property tabu</name>
    <solver>
      <localSearch>
        <selector>
          <moveFactoryClass>org.drools.planner.examples.nqueens.solver.move.factory.NQueensMoveFactory</moveFactoryClass>
        </selector>
        <acceptor>
          <completePropertyTabuSize>5</completePropertyTabuSize>
        </acceptor>
        <forager>
          <pickEarlyType>NEVER</pickEarlyType>
        </forager>
      </localSearch>
    </solver>
  </solverBenchmark>
</solverBenchmarkSuite>

This benchmarker will try 3 configurations (1 solution tabu, 1 move tabu and 1 property tabu) on 2 data sets (32 and 64 queens), so it will run 6 solvers.

Every solverBenchmark entity contains a solver configuration (for example a local search solver) and one or more unsolvedSolutionFile entities. It will run the solver configuration on each of those unsolved solution files. A name is optional and generated if absent. The common part of multiple solverBenchmark entities can be extracted to the inheritedSolverBenchmark entity, but that can still be overwritten per solverBenchmark entity.

You need to specify a benchmarkDirectory (relative to the working directory). The best solution of each solver run and a handy overview HTML webpage will be written in that directory.

The benchmarker supports outputting statistics as graphs and CSV (comma separated values) files to the benchmarkDirectory.

To configure graph and CSV output of a statistic, just add a solverStatisticType line:


<solverBenchmarkSuite>
  <benchmarkDirectory>local/data/nqueens/solved</benchmarkDirectory>
  <solverStatisticType>BEST_SOLUTION_CHANGED</solverStatisticType>
  ...
</solverBenchmarkSuite>

Multiple solverStatisticType entries are allowed. Some statistic types might influence performance noticeably. The following types are are supported: