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

304 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 步) 跳过校准
- 或只在校准目录为空时执行
```python
# 建议改动
_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+ 个模块级全局变量:
```python
box_a = None
alpha = None
ATOM_IDS = None
...
```
所有算法函数直接依赖这些全局变量,导致:
- 无法并发运行两个模拟
- 无法单元测试单个函数
- 函数签名无法自文档化
**建议**:将全局状态封装为 `SimulationState` 类:
```python
@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 个模块级变量:
```python
DISPLAY_X = ...
DISP_ALL_X = ...
N_FRAMES = ...
frame_idx = 0
```
**建议**:封装为 `AnimationData``CameraState`
### 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`配置 | 旧注释格式 | 新注释格式 |
**建议**
```yaml
# 统一模板
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 列表更自然:
```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/O`save_display_txt` / `load_display_txt` 读写一致性)添加测试
- 添加一个 `examples/case00` 最小验证案例(2 个原子,10 步)
- CI`pytest` + 简单的集成测试脚本
### 5.2 缺少类型标注(中优先级)
```python
# 现状
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.txt``save_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/b``ball_color` 列表