在 Python Language Summit 2026 上,Kushal Das 展示了 Spicycrab:一个面向 Python 开发者的 Python-to-Rust 转译器。它瞄准的是一个很现实的矛盾——团队希望保留 Python 的开发效率,却又不想让 CPU 密集型代码一直受解释执行成本限制,更不希望为了优化少数热点而要求所有人先掌握 Rust。
Spicycrab 的吸引力并不只是“把一种语言翻译成另一种语言”。真正值得关注的问题是:它能否让开发者继续用 Python 表达业务逻辑,同时把适合静态化、编译化的部分转换为更高效的 Rust 实现。
它试图缩短哪一段性能优化路径
传统 Python 项目遇到性能瓶颈时,常见路线包括:
- 调整算法和数据结构;
- 使用 NumPy 等已经编译好的库;
- 借助多进程绕开部分运行时限制;
- 用 C、Cython 或 Rust 重写热点;
- 将计算密集任务拆成独立服务。
其中,“用 Rust 重写”往往能获得不错的性能和内存安全性,但成本并不只来自语法学习。开发者还要处理 Python 与 Rust 之间的数据转换、异常映射、构建流程、二进制分发和跨平台兼容。
Spicycrab 的定位,是把其中一部分工作自动化:Python 开发者仍然维护 Python 源码,由转译器生成 Rust 方向的实现。根据现有摘要,尚不能假设它支持全部 Python 语法,也不能断言其命令行接口、生成物格式或性能提升比例。更合理的期待是:它优先帮助结构明确、类型相对稳定、计算密集的代码,而不是无差别加速整个应用。
哪些代码最值得拿来尝试
转译器通常更容易处理控制流清晰、外部依赖少的纯计算函数。例如数值循环、解析器中的局部计算、批量规则判断以及算法模块,都比高度动态的框架代码更适合作为候选。
下面这个脚本可以直接运行,用于建立一个纯 Python 性能基线:
from math import isqrt
from time import perf_counter
def count_primes(limit: int) -> int:
count = 0
for number in range(2, limit):
prime = True
boundary = isqrt(number)
for divisor in range(2, boundary + 1):
if number % divisor == 0:
prime = False
break
if prime:
count += 1
return count
if __name__ == "__main__":
limit = 100_000
started = perf_counter()
result = count_primes(limit)
elapsed = perf_counter() - started
print(f"primes below {limit}: {result}")
print(f"elapsed: {elapsed:.3f}s")
保存为 prime_baseline.py 后运行:
python prime_baseline.py
这类函数具备几个适合转译实验的特点:输入和输出简单、没有运行时修改对象、主要成本集中在整数运算与循环中,而且结果容易验证。实际接入 Spicycrab 时,应以项目公开文档中的命令和支持语法为准;来源摘要没有给出稳定 CLI,因此不宜凭空假设 spicycrab build 一类命令已经存在。
相反,下面这些代码需要谨慎评估:
- 频繁使用
getattr、setattr或运行时生成属性; - 大量依赖 monkey patch;
- 深度绑定 Django、Flask 等框架对象生命周期;
- 依赖 CPython 内部行为或 C 扩展对象;
- 输入类型频繁变化,且函数内部混合网络、磁盘和数据库 I/O。
I/O 密集任务通常也不是转译器的首要收益区。一个接口的大部分时间若花在等待数据库上,把几毫秒的 Python 计算转成 Rust,并不会解决慢查询。
接入时不要只比较“跑得快不快”
转译后的实现必须先证明语义一致,再谈性能。可以把原始 Python 模块保留下来,并针对生成模块运行同一组测试。
假设原始实现位于 prime_baseline.py,Spicycrab 生成的扩展最终可通过 prime_accelerated 导入,可以这样编写回归测试。这里的模块名只是接入示例,需要替换成工具实际生成的名称:
# test_equivalence.py
import pytest
from prime_baseline import count_primes as python_count_primes
from prime_accelerated import count_primes as accelerated_count_primes
@pytest.mark.parametrize("limit", [0, 1, 2, 3, 10, 100, 1_000])
def test_same_result(limit: int) -> None:
assert accelerated_count_primes(limit) == python_count_primes(limit)
def test_rejects_invalid_input() -> None:
with pytest.raises((TypeError, ValueError)):
accelerated_count_primes(-1)
运行测试:
python -m pip install pytest
pytest -q
测试边界需要覆盖的不只是正常结果,还包括:
- 大整数是否溢出;
None、负数和错误类型如何处理;- Python 异常是否被保留或映射;
- Unicode、字节串和容器的转换是否一致;
- 并发调用时是否安全;
- 不同操作系统和 Python 版本能否加载生成物。
性能测试也应尽量贴近生产输入。不要只运行一次,更不要把编译时间、模块首次加载时间与函数执行时间混在一起。对于很短的函数,还要计算跨语言边界的数据转换成本;如果每次调用只做几十纳秒到几微秒的工作,封装和转换可能吞掉收益。
更稳妥的采用方式:从一个热点函数开始
Spicycrab 所代表的方向很有价值:把 Rust 作为生成目标,而不是把 Rust 学习门槛直接转嫁给每位 Python 开发者。但自动转译不会消除语言语义差异,也不会自动修复低效算法。
在真实项目中,可以按下面的顺序试点:
- 用
cProfile、py-spy 或现有 APM 找到真实热点,不凭感觉选择模块; - 先优化算法,确认瓶颈确实来自 Python 计算;
- 挑选一个输入输出简单、测试充分的纯函数;
- 保存 Python 实现作为正确性基线和回退路径;
- 对转译结果进行等价性、性能和内存测试;
- 在 CI 中覆盖目标 Python 版本、操作系统和 CPU 架构;
- 只有在端到端指标显著改善时,才扩大使用范围。
对于 Python 团队来说,Spicycrab 最值得验证的不是“能不能把所有 Python 都变成 Rust”,而是“能不能把最贵的那一小段 Python,低风险地变成可部署的高性能实现”。如果它能守住语义兼容、构建稳定和调试可用这三条边界,就可能成为 Python 性能工具箱里一条很实用的新路径。