You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级OptaPlanner/Timefold后排课应用性能骤降,求优化方案

OptaPlanner升级至Timefold后性能下降的优化方案

我有一个基于OptaPlanner 8.22.1.Final的排课应用,升级至Timefold 1.1.0(同步将JDK从11升级至17)后,性能测试用例的执行时间增加约100%,仅切换依赖库未修改应用代码。同时测试引入Bavet的OptaPlanner 8.37.0.Final等版本,均出现性能下降问题,预期的小幅提速未实现。

测试详情

测试用例1

升级前(OptaPlanner 8.22.1.Final + JDK11)

2023-09-10 13:02:17,390 INFO Solving started: time spent (5), best score (-730init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), move thread count (4), random (JDK with seed 0).
2023-09-10 13:02:17,902 INFO Construction Heuristic phase (0) ended: time spent (517), best score (-40hard/-2265medium/0soft), score calculation speed (32158/sec), step total (365).
2023-09-10 13:03:31,283 INFO Local Search phase (1) ended: time spent (73898), best score (0hard/0medium/0soft), score calculation speed (24932/sec), step total (28873).
2023-09-10 13:03:31,283 INFO Solving ended: time spent (73898), best score (0hard/0medium/0soft), score calculation speed (24979/sec), phase total (2), environment mode (REPRODUCIBLE), move thread count (4).

升级后(Timefold 1.1.0 + JDK17)

2023-09-10 15:38:24,216 INFO Solving started: time spent (11), best score (-730init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), move thread count (4), random (JDK with seed 0).
2023-09-10 15:38:24,590 INFO Construction Heuristic phase (0) ended: time spent (385), best score (-40hard/-2265medium/0soft), score calculation speed (87852/sec), step total (365).
2023-09-10 15:42:03,882 INFO Local Search phase (1) ended: time spent (219677), best score (0hard/-10medium/0soft), score calculation speed (35648/sec), step total (31041).
2023-09-10 15:42:03,883 INFO Solving ended: time spent (219677), best score (0hard/-10medium/0soft), score calculation speed (35734/sec), phase total (2), environment mode (REPRODUCIBLE), move thread count (4).

测试用例2

升级前(OptaPlanner 8.22.1.Final + JDK11)

2023-09-10 13:03:32,508 INFO Solving started: time spent (16), best score (-3796init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), move thread count (4), random (JDK with seed 13).
2023-09-10 13:03:34,728 INFO Construction Heuristic phase (0) ended: time spent (2236), best score (-10hard/-6460medium/0soft), score calculation speed (40084/sec), step total (1898).
2023-09-10 13:08:37,166 INFO Local Search phase (1) ended: time spent (304674), best score (0hard/0medium/0soft), score calculation speed (13550/sec), step total (83120).
2023-09-10 13:08:37,167 INFO Solving ended: time spent (304675), best score (0hard/0medium/0soft), score calculation speed (13742/sec), phase total (2), environment mode (REPRODUCIBLE), move thread count (4).

升级后(Timefold 1.1.0 + JDK17)

2023-09-10 15:42:04,616 INFO Solving started: time spent (32), best score (-3796init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), move thread count (4), random (JDK with seed 13).
2023-09-10 15:42:07,385 INFO Construction Heuristic phase (0) ended: time spent (2801), best score (-10hard/-6460medium/0soft), score calculation speed (64265/sec), step total (1898).
2023-09-10 15:52:28,340 INFO Local Search phase (1) ended: time spent (623756), best score (0hard/0medium/0soft), score calculation speed (12726/sec), step total (82742).
2023-09-10 15:52:28,341 INFO Solving ended: time spent (623757), best score (0hard/0medium/0soft), score calculation speed (12954/sec), phase total (2), environment mode (REPRODUCIBLE), move thread count (4).

优化建议

  • 调整Bavet计分器配置:OptaPlanner后期版本及Timefold默认使用Bavet替代Drools作为计分引擎,部分旧版Drools规则写法在Bavet下可能存在冗余计算。检查约束定义,避免不必要的实体Join操作,对频繁访问的属性添加索引(如在实体类上标注@PlanningId,或在约束中使用indexedBy),简化复杂约束的嵌套逻辑。

  • 优化JDK17的GC参数:JDK17默认GC为G1,其行为与JDK11的G1存在差异。尝试调整GC参数,例如增大堆内存(-Xmx16g)、设置G1的最大停顿时间(-XX:MaxGCPauseMillis=200),或切换至ZGC(-XX:+UseZGC,适合大堆低延迟场景),减少GC停顿对求解性能的影响。

  • 显式配置Local Search策略:从日志可见,升级后Local Search阶段耗时显著增加,且测试用例1未达到最优分数。Timefold可能调整了Local Search的默认参数,建议显式配置搜索策略:指定acceptor为lateAcceptance(与旧版OptaPlanner默认一致),调整forager的acceptedCountLimit参数,或设置明确的终止条件(如termination.spentLimit=70s)匹配旧版求解时长。

  • 临时回退至Drools计分器:若确认Bavet是性能瓶颈,可在Timefold中显式启用Drools:在SolverConfig中配置scoreDirectorFactory.scoreDrl指向原规则文件,或通过系统属性-Dtimefold.scoreDirectorFactory.bavet=false关闭Bavet,验证性能是否恢复。

  • 分析约束性能瓶颈:使用Timefold的约束性能分析工具,启用scoreCalculationLogging日志输出,或通过ConstraintVerifier测试单个约束的执行耗时,定位并优化耗时最长的约束规则。

  • 调整线程配置:尽管moveThreadCount设置为4,JDK17的线程调度机制可能与JDK11不同。尝试设置moveThreadCount=auto让系统自动适配CPU核心数,或测试不同线程数(如2、8),找到最优的并行求解线程配置。

内容的提问来源于stack exchange,提问作者user2544507

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:34:54