---
title: "保存并重复执行同一计划"
description: "把 planning 从重复 contraction 中移出，并区分可保存的执行计划与进程内编译对象。"
eyebrow: "教程"
---

## 跨进程保存与加载 {#save-load}

```python
from arctn import ArcTNExecutionPlan, arctn_plan

plan = arctn_plan(
    inputs, output, size_dict,
    preset="heavy", seed=0,
    target_size=2**24, slicing_mode="fixed",
)
plan.save("plan.json")

loaded = ArcTNExecutionPlan.load("plan.json")
loaded.validate(inputs, output, size_dict, arrays=arrays)
result = loaded.execute(arrays, backend="native")
```

`ArcTNExecutionPlan` 保存规范化网络、SSA path 和精确切片集合。`load()` 与 `execute()` 都不会重新运行 planner，因此另一个进程可以重放同一计划。

## 同一进程内编译并重复执行 {#compile}

```python
unsliced = arctn_plan(
    inputs, output, size_dict, preset="heavy", seed=0
)
compiled = unsliced.compile(backend="native")
result_1 = compiled.execute(arrays_1)
result_2 = compiled.execute(arrays_2)
print(compiled.stats())
```

- 每次 arrays 的数量和 shape 必须和编译计划一致；同一次执行的全部数组必须使用同一种受支持 dtype。编译时不固定 dtype。
- ArcTNExecutionPlan 是 backend-neutral、可保存的计划；ArcTNCompiledContraction 是 backend-specific、进程内执行对象。
- 有切片 plan 不能 compile；应继续使用 plan.execute()，或调用 plan.to\_tree() 交给 Cotengra。

## 复用的适用条件 {#amortization}

若规划时间为 P、编译时间为 K、单次执行时间为 E，执行 N 次时，一次性规划并复用的总时间近似为 P + K + N×E。反复调用 `arctn_contract` 会把 planning 重复 N 次。

> **摊销模型的适用范围**
>
> 这条关系只说明时间组成。跨库速度仍取决于相同网络、dtype、backend、线程设置和同步边界下的实测。
