Search code examples
performanceoptaplanner

How to speed up SolverManager.solveAndListen


Every time I run solverManager.solveAndListen(...) to start OptaPlanner, it takes upwards of 500ms to initialize it, and the actual solving starts after that.

Is there any way to dramatically speed this up? I ran a benchmark on it, but I'm not sure where it's spending all its time.

I'm doing CVRPTWPD and currently testing 3 Vehicles with 167 Visits, but lowering the Visits seems to have no impact, so it's got to be something else.

It's okay for my scenario if the first call to solveAndListen is slow, but I need subsequent calls to be very fast (under 30ms would be ideal).

Thanks

***Edit:

I run the following code once:

solverConfig = SolverConfig.createFromXmlResource("solverConfig.xml") // takes 315ms
solverManager = SolverManager.create(solverConfig, SolverManagerConfig()) // takes 1409ms
scoreManager = ScoreManager.create(solverManager) // takes 556ms

Then I run a method many times which:

  1. Loads/resets the entities (used by this::findById)

  2. Runs this (I wrapped it in a timer), which takes ~500ms each time:

solverManager.solveAndListen(
            1,
            this::findById,
            this::save
        )

Solution

  • Possible culprits:

    • The solverAndListen() transfers to a solver thread for the solver thread pool. But 500ms is unlikely to be here.
    • The solver thread calls SolverFactory.createSolver(). Creating the solver isn't as fast yet as it could be (although in optaplanner 8.0 we had API changes that allow us to internalize the solver config now, we still don't do it yet.)
    • Actual solving start: first from scratch score calculation, first planning clone, etc.

    I would bet on the 2th item. Especially if you use scoreDRL, then it would parse the scoreDRL every time and build Drools KieBase every time, which is expensive.