Skip to content

perf(bean): 优化FastBeanCopier默认后端与缓存策略#352

Open
zhou-hao wants to merge 14 commits into
5.0.xfrom
5.0.x-refactor-copy
Open

perf(bean): 优化FastBeanCopier默认后端与缓存策略#352
zhou-hao wants to merge 14 commits into
5.0.xfrom
5.0.x-refactor-copy

Conversation

@zhou-hao

@zhou-hao zhou-hao commented May 7, 2026

Copy link
Copy Markdown
Member

目的

  • 继续收口 FastBeanCopier 默认 backend、缓存策略与跨 classloader 兼容行为。
  • 在保证兼容性的前提下优先提升热路径命中稳定性,并为 native / 受限运行时保留可靠 fallback。

核心变动

默认 backend 与运行时选择

  • 默认 backend 调整为 asm-accessor
  • 新增 FastBeanCopierBackendSelector
    • 支持 hsweb.fast-bean-copier.backend 显式指定 backend
    • 支持 hsweb.fast-bean-copier.disable-codegen 禁用 runtime codegen
    • 探测 org.graalvm.nativeimage.imagecode / hsweb.fast-bean-copier.native-image
  • native / disable-codegen 环境下,默认回退到 reflection-accessor

缓存与 classloader 策略

  • FastBeanCopierSupport 增加 backend cache 与动态 loader 的 volatile copier cache。
  • 动态 classloader 场景统一回退 reflection-accessor,避免 runtime codegen 在跨 loader/受限环境下失效。
  • 热路径缓存改为强命中优先:
    • volatile copier cache 使用强缓存
    • ClassDescriptions 改为按 classloader 分段的强缓存
    • converter 子缓存改为按 classloader 分段的强缓存
    • accessor 泛型解析缓存 GENERIC_CACHE 改为强缓存
  • 对外新增:
    • FastBeanCopier.clearCache()
    • FastBeanCopier.clearCache(ClassLoader)
  • 保留 FastBeanCopier.DEFAULT_CONVERT 兼容入口,并标记弃用。

转换与兼容性补强

  • FastBeanCopierConverterSupport 引入 conversion plan cache。
  • 补齐 collection / map 泛型转换、enum lookup、bean-like target 等子路径缓存。
  • 支持动态 loader 相关 converter / class description / accessor 缓存显式释放。

测试与基准

  • 补充 FastBeanCopierSupportTest,覆盖:
    • 默认 backend 选择
    • native hint fallback
    • backend 显式 override
    • DEFAULT_CONVERT 泛型集合/Map 转换兼容
    • 跨 classloader 复制
    • 动态 loader reflection fallback
    • clearCache(ClassLoader) 回收与重建
  • 更新 FastBeanCopierBenchmarkSummary.md
  • 更新 FastBeanCopierJmhRunner,支持 include/forks 参数化

设计与测试目标

  • 设计稿:不适用;本次为 hsweb-core 基础工具性能与缓存策略优化。
  • 用户确认:已确认并提交到当前 PR 分支。
  • 测试目标:覆盖默认 backend、缓存释放、动态 classloader、转换兼容与既有 FastBeanCopier 回归路径。
  • 注释 / 公共契约:已有缓存生命周期与动态 classloader 回收说明;未新增 SPI。
  • 数据权限:不适用;不涉及 CRUD / AssetsHolder。
  • 数据库兼容与性能:不适用;不涉及 SQL。
  • 链路追踪:不适用;本次为通用 bean copy 工具,不涉及关键业务链路。
  • MBean 运维可观测性:不适用;未新增常驻任务、队列或后台执行器。

测试结果

  • 命令:mvn -pl hsweb-core -am -Dtest=FastBeanCopierSupportTest,FastBeanCopierTest -Dsurefire.failIfNoSpecifiedTests=false test
  • 新增/更新测试:FastBeanCopierSupportTest 覆盖 backend 选择、缓存和 classloader 兼容;FastBeanCopierTest 覆盖既有复制回归路径。
  • 单元测试:33 passed, 0 failed, 0 skipped
  • 集成测试:不适用;未涉及数据库、消息、事件、协议、跨模块边界、外部依赖或启动装配。
  • 压力测试:不适用;性能对比使用 JMH 基准结果。
  • 覆盖率:
    • hsweb-core overall line 43.74%, branch 40.25%
    • AccessorFastBeanCopierBackend line 88.24%, branch 87.88%
    • FastBeanCopierSupport line 78.91%, branch 68.42%
    • FastBeanCopierConverterSupport line 70.33%, branch 59.26%
    • ClassLoaderScopedClassCache line 88.89%, branch 75.00%
    • FastBeanCopierBackendSelector line 77.27%, branch 52.38%

代表性性能结果

JMH 结果文件:hsweb-core/target/jmh-results/fast-bean-copier.json

单位 us/op,越小越好:

  • simple bean -> bean
    • asm-accessor: 0.100
    • javassist: 0.102
    • reflection-accessor: 0.331
  • complex bean -> bean
    • javassist: 5.547
    • asm-accessor: 6.495
    • reflection-accessor: 8.125
  • bean -> map
    • asm-accessor: 0.908
  • heterogeneous map -> bean
    • asm-accessor: 7.429
  • conversion-heavy map -> bean
    • asm-accessor: 9.530
  • collection-heavy map -> bean
    • asm-accessor: 0.857
  • nested-heavy map -> bean
    • asm-accessor: 1.177

结论:asm-accessor 已具备默认 backend 的综合优势;仅 complex bean -> bean 单项上 javassist 仍领先。

文档同步情况

  • 已同步:hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierBenchmarkSummary.md
  • 未同步:README 未修改;FastBeanCopier 对外用法无长期总览变更。
  • 说明:测试/性能证据放在 PR 与 benchmark summary 中,未新增独立任务流水文档。

风险与说明

  • 影响范围:hsweb-core 的 FastBeanCopier 复制、转换和缓存路径。
  • 注释 / 公共契约:缓存生命周期与动态 classloader 清理边界已有说明;未新增 SPI / public contract 破坏性变更。
  • 链路追踪 / 可观测性:不涉及;本次为基础工具能力增强。
  • MBean / 运维可观测性:不涉及;未新增常驻运维对象。
  • 未覆盖场景:目前不能宣称完整 native image 适配完成;只是具备 native/受限环境下的 fallback 基础。
  • 已知限制:仍存在受限反射路径,例如 setAccessible(true) 相关集合构造与 accessor 实现;通过 exec-maven-plugin 运行 forked JMH 时仍会遇到 org.openjdk.jmh.runner.ForkedMain classpath 问题,当前基准结果以 non-forked 相对对比为主。

@zhou-hao zhou-hao changed the title refactor(bean): 重构 FastBeanCopier 复制后端并补齐兼容性验证 refactor(bean): 重构并优化 FastBeanCopier 复制后端 May 28, 2026
@zhou-hao
zhou-hao marked this pull request as ready for review May 28, 2026 01:21
@zhou-hao zhou-hao changed the title refactor(bean): 重构并优化 FastBeanCopier 复制后端 perf(bean): 优化FastBeanCopier默认后端与缓存策略 May 31, 2026
zhou-hao added 3 commits May 31, 2026 13:11
# Conflicts:
#	hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
#	hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java
@zhou-hao zhou-hao changed the title perf(bean): 优化FastBeanCopier默认后端与缓存策略 perf(bean): 优化FastBeanCopier复制能力与缓存策略 Jul 14, 2026
@zhou-hao
zhou-hao force-pushed the 5.0.x-refactor-copy branch from 308e299 to 670effb Compare July 14, 2026 09:47
@zhou-hao zhou-hao changed the title perf(bean): 优化FastBeanCopier复制能力与缓存策略 perf(bean): 优化FastBeanCopier默认后端与缓存策略 Jul 14, 2026
zhou-hao added 2 commits July 14, 2026 19:19
# Conflicts:
#	.github/workflows/pull_request_5x.yml
#	hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant