Files
dynamics/optimization/workbuddy.md
T
admin 782422e800 docs: 添加优化建议文档 optimization/workbuddy.md
涵盖架构/性能/代码质量/配置/测试/引擎一致性/UX 等
9 个方面、26 条具体建议,标注实施优先级和工作量。
2026-06-12 15:15:10 +08:00

8.4 KiB
Raw Blame History

Dynamics 项目优化建议

分析日期:2026-06-12 版本:main (43 commits)


1. 架构优化

1.1 compute.py 拆分(高优先级)

现状compute.py 1618 行,混合了以下职责:

  • 物理引擎(数值积分方法 ~10 个函数)
  • 文件 I/OJSON/text 读写)
  • 外部引擎管理(subprocess 调用)
  • 参数加载与解析
  • 主入口 main()

建议:按职责拆分为独立模块

compute/
├── __init__.py          # 导出公共 API
├── core.py              # 物理引擎: 数值积分方法, 力的计算 (~200 行)
├── io.py                # 文件 I/O: save/load display/trajectory (~300 行)
├── params.py            # 参数加载: load_coord_file, load_bond 等 (~150 行)
├── runner.py            # 运行管理: run_simulation, run_engine, run_from_config (~200 行)
├── engine_helper.py     # 外部引擎: 校准, subprocess, 进度监控 (~150 行)
└── main.py              # 主入口: main(), if __name__ == "__main__" (~30 行)

收益:可单独测试物理算法、文件读写、引擎调用

1.2 外部引擎代码重构(中优先级)

现状C/C++/Fortran 引擎各自实现了一套:

  • JSON 读取/写入(3 套独立实现)
  • 物理算法(复制粘贴)
  • display.txt / trajectory.txt 输出

建议

  • C 和 C++ 引擎共用头文件/函数库
  • 物理算法提取为公共库(engines/common/
  • Fortran 更新支持 save_trajectory 兼容

2. 性能优化

2.1 外部引擎校准耗时(高)

现状run_engine() 每次执行前先跑 1000 步校准测速(_calib_nt = min(1000, max(100, total_steps // 10))),对短时运行(~1000 步)校准占比高达 50%。

建议

  • 缓存校准结果:按 (engine, NT, DT, NSTEP, n_atoms) 哈希缓存
  • 或对短运行 (<5000 步) 跳过校准
  • 或只在校准目录为空时执行
# 建议改动
_calib_cache = os.path.join(script_dir, "engines", engine, "_calib_cache.json")
if os.path.exists(_calib_cache):
    with open(_calib_cache) as f:
        _calib_data = json.load(f)
    if _calib_data.get("key") == _calib_key:
        _step_time = _calib_data["step_time"]
        _overhead = _calib_data["overhead"]
        skip_calibration()

2.2 display.txt 读取加速(已完成)

现状:已从逐行 split()+float() 改为 np.genfromtxt() 批量解析,200帧×120原子 加载仅 0.087s(测试已通过)。

2.3 Python 引擎性能(低)

现状:Python 引擎比 C 引擎慢约 6-8 倍(43s vs 7s for 10 万步)。对 50 万步以上的长时间模拟不适用。

建议

  • 使用 Numba JIT 加速力的计算
  • 或使用 numpy.vectorize 替代 Python 循环(力的计算中已部分使用 numpy 数组操作)
  • 文档中注明 Python 引擎仅适用于小规模测试

2.4 校准数据的进度条(已修复)

校准后进度条使用实时帧号更新,不再使用时间估算,避免了 0% → 100% 跳变。但注意校准本身不显示进度。


3. 代码质量

3.1 消除全局变量(高优先级)

现状compute.py 定义了 40+ 个模块级全局变量:

box_a = None
alpha = None
ATOM_IDS = None
...

所有算法函数直接依赖这些全局变量,导致:

  • 无法并发运行两个模拟
  • 无法单元测试单个函数
  • 函数签名无法自文档化

建议:将全局状态封装为 SimulationState 类:

@dataclass
class SimulationState:
    box_a: float = 10.0
    atom_ids: np.ndarray = None
    atom_masses: np.ndarray = None
    ...

def leapfrog(state: SimulationState, ...):
    ...

3.2 draw.py 全局变量(中优先级)

现状:类似的问题,draw.py 用了 ~30 个模块级变量:

DISPLAY_X = ...
DISP_ALL_X = ...
N_FRAMES = ...
frame_idx = 0

建议:封装为 AnimationDataCameraState

3.3 废弃文件清理(低优先级)

以下文件可能已废弃或重复:

文件 行数 判断
sample.py 184 已不再被调用(抽帧已移至引擎内部)
build_release_zip.py - 打包脚本,非核心功能
export_web_data.py - 导出脚本,非核心功能
migrate_npz_outputs.py - 迁移脚本,一次性使用
tools/NumericalMethods.py - 可能已过时
build/ (CMake 相关) - 与独立引擎编译无关

4. 配置管理

4.1 input.txt 格式统一(高优先级)

现状6 个案例的 input.txt 格式不统一:

字段 case01 case06
save_trajectory 缺失
camera_distance/elevation/azimuth 缺失
move_camera 缺失
step_sample 仍然写 1 已改为 0
step_plot配置 旧注释格式 新注释格式

建议

# 统一模板
flow:
  step_simulate: 1
  step_sample: 0           # 引擎已内置抽帧
  step_animation: 1
  save_trajectory: 0       # 默认不保留

physics:
  box_a: 10.0
  G: [0, 0, -9.8]
  method: leapfrog
  T_total: 10.0
  NSTEP: 100
  DT: 0.001

render:
  use_marker: 0
  alpha: [0.0]*6
  ball_color: [0.9, 0.2, 0.2]
  box_color: [0.8, 0.8, 0.85]
  camera:
    distance: 40.0
    elevation: 0
    azimuth: 0
    move: false

4.2 YAML 结构优化(中优先级)

现状ball_color_r/g/b 三个独立的键,YAML 列表更自然:

# 当前
ball_color_r: 0.90
ball_color_g: 0.20
ball_color_b: 0.20

# 建议
ball_color: [0.90, 0.20, 0.20]

5. 测试与质量

5.1 缺少测试(高优先级)

现状:无单元测试、无集成测试。每次修改只能手动跑案例。

建议

  • compute.py 的物理算法(Leapfrog、Euler 等)添加 pytest 测试
  • 为文件 I/Osave_display_txt / load_display_txt 读写一致性)添加测试
  • 添加一个 examples/case00 最小验证案例(2 个原子,10 步)
  • CIpytest + 简单的集成测试脚本

5.2 缺少类型标注(中优先级)

# 现状
def leapfrog(x, y, z, vx, vy, vz, dt, m, g, b):

# 建议
def leapfrog(
    x: np.ndarray, y: np.ndarray, z: np.ndarray,
    vx: np.ndarray, vy: np.ndarray, vz: np.ndarray,
    dt: float, m: np.ndarray, g: np.ndarray, b: np.ndarray
) -> tuple[np.ndarray, np.ndarray, np.ndarray,
           np.ndarray, np.ndarray, np.ndarray]:

6. 引擎一致性

6.1 Fortran 引擎更新(高)

现状Fortran 引擎不支持 save_trajectory=0 模式,总是写 JSON 格式的 trajectory.txt。需要:

  1. 读取 save_trajectory 参数
  2. 计算时按 NSTEP 采样
  3. 写 display.txt 新格式
  4. 按条件跳过 trajectory.txt 输出

参考 C 引擎的 write_display_txt 实现(约 40 行代码)。

6.2 参数默认值一致性(中)

各引擎的 SimParams 默认值不一致:

参数 C C++ Fortran
box_a 无默认 10.0 10.0 (代码中)
method leapfrog leapfrog leapfrog
save_trajectory 0 1 不支持

7. 用户体验

7.1 进度条改进(低)

  • 外部引擎校准阶段不显示进度(建议加 "校准中…" 文本)
  • Fortran 引擎支持时,增加进度消息

7.2 缓存一致性(已修复)

已修复:display.txtsave_trajectory=0 时不再保留 trajectory.txt,外部引擎路径总是从 trajectory.txt 重新抽帧。

7.3 move_camera.txt 实时生效(已修复)

draw.py 直接读取 move_camera.txt,修改后重启动画即可生效,无需重新跑模拟。


8. 实施优先级

优先级 内容 预估工作量
P0 Fortran 引擎支持 save_trajectory=0 2-3h
P0 全局变量封装为 SimulationState 3-4h
P1 compute.py 模块拆分 4-6h
P1 添加单元测试 (pytest) 3-5h
P1 input.txt 格式统一 (6个案例) 1-2h
P2 校准缓存加速 1-2h
P2 废弃文件清理 0.5h
P3 draw.py 封装 AnimationData 2-3h
P3 类型标注 2-3h

9. 快速 wins(半小时内可完成)

  1. 更新 Fortran 引擎(参考 C 的 write_display_txt 迁移)
  2. 删除 sample.py(已废弃)
  3. 统一 6 个案例的 input.txt 格式
  4. 添加 save_trajectory 到 case01-05 的 default 配置
  5. 统一 ball_color_r/g/bball_color 列表