317. PyPy 启动脚本

为手动运行添加明确的 PyPy 启动脚本。

317 / 356 · tests/chapter_10_performance/test_317_pypy_launchers.py

需要在仓库根目录创建的文件

launcher.sh
launcher.cmd

为什么需要这一步

PyPy 可以提升模拟器核心的吞吐量,因为模拟器的大部分代码都是运行在紧密循环中的 Python 代码。这一步没有去修改 pyproject.toml 或强制所有学员默认使用 PyPy,而是添加了明确的手动启动脚本。

创建这些启动脚本之后,学员在进行手动性能实验时应当使用它们,而不是直接用 CPython 启动 main.py。

Linux/macOS 用法

sh launcher.sh

或者,如果已经添加了可执行权限:

chmod +x launcher.sh
./launcher.sh

Windows 命令提示符用法

launcher.cmd

预期的手动信号

当模拟器核心从 PyPy 中受益时,之前添加的 FPS 计数器数值应当会提升。在采用更快的 pygame 帧缓冲上传路径之后,PyPy 可能会让模拟器运行得比真实 NES 速度更快。在教程开发过程中,更快的 pygame 绘制路径加上 PyPy,在手动 ROM 路径上大约达到了 90-120 FPS。

具体数值取决于机器和 ROM 状态,但现在终端输出的 FPS 就是可以用来比较的依据:

fps=30.0    # example after faster pygame drawing on CPython
fps=100.0   # example after faster pygame drawing + PyPy launcher

如果此时 FPS 高于 NES 速度,这就是一个很好的证据,说明下一步应当添加帧节奏 / 预期速度控制,以避免手动游戏运行得太快。

两个启动脚本最终委托执行的命令

uv run --python pypy python main.py

Linux/macOS 示例

#!/usr/bin/env sh

# Run NES with PyPy through uv.
# Usage:
#     sh launcher.sh
# or:
#     chmod +x launcher.sh
#     ./launcher.sh

uv run --python pypy python main.py

Windows CMD 示例

@echo off

REM Run NES with PyPy through uv.
REM Usage:
REM     launcher.cmd

uv run --python pypy python main.py

重要的测试规则

这些测试不得执行这些启动脚本。运行它们会启动手动的 pygame 前端,并需要本地 ROM 文件。我们只是以文本方式检查这些文件。

本步骤范围之外

  • 更改 pyproject.toml 中的默认 Python
  • 从 pytest 中启动 PyPy
  • 打开 pygame 窗口
  • 测量 FPS
  • 优化渲染

运行本课

uv run pytest tests/chapter_10_performance/test_317_pypy_launchers.py -v