ty 基准测试深度解析:CLI 全量检查与语言服务器增量的真实性能数据
【免费下载链接】tyAn extremely fast Python type checker and language server, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ty2/ty
本篇技术指南以仓库根目录下的 BENCHMARKS.md 为唯一主体,完整呈现 ty(一款用 Rust 编写的极速 Python 类型检查器与语言服务器)在 macOS Apple M3 Max 平台、9 个真实开源项目上的官方基准测试结果,覆盖 CLI 全量类型检查、LSP 增量编辑与诊断获取三大场景,并对比 Pyrefly、Pyright、mypy 三款主流工具。读完本文,你将能够准确理解 ty 的官方性能数据、复现测试的方法要点,以及正确解读这些数字所代表的工程含义。
测试环境与方法概述
所有基准测试均在macOS(Apple M3 Max 16 核,128 GB 内存)上计算得出,参与对比的工具及版本如下:
| 工具 | 版本 | 语言/形态 |
|---|---|---|
| ty | 0.0.55 | Rust,PyPI 发布 |
| Pyrefly | 1.1.1 | Python,PyPI 发布 |
| Pyright | 1.1.410 | Node.js,npm 发布 |
| mypy | 2.1.0 | Python,PyPI 发布 |
需要强调的是,基准性能会因操作系统而异、因项目而异。因此该文档特意选取了多个不同类型、不同规模的真实项目作为测试样本,以尽量代表真实世界的使用形态,包括:
- 代码格式化/静态分析类:Black、isort
- Web 框架/库:discord.py、Jinja
- 智能家居大型单体项目:Home Assistant
- 数据科学/数值计算:pandas、pandas-stubs、PyTorch
- 工作流编排:Prefect
测试覆盖两大维度:一是CLI(ty check全量类型检查的端到端耗时,使用 hyperfine 风格多次运行取均值);二是LSP(语言服务器的增量编辑与获取诊断两项交互,使用 pytest-benchmark 输出)。关于基准测试的运行说明,原文档给出了明确指引(ty_benchmark/README.md),下文将结合仓库内相关文档逐项展开。
CLI 基准测试:全量类型检查的端到端耗时
CLI 部分使用多次运行取均值的计时方式,输出形如Time (mean ± σ)、Range (min … max)与运行次数(runs)。每个工具均出现Warning: Ignoring non-zero exit code.的提示——这是因为类型检查器在发现类型错误时会以非零退出码结束,hyperfine 对此给出警告,但不影响计时结果的有效性。
逐项目原始数据
以 black 项目为例,原始输出完整保留了每次基准的细节:
black ----- Benchmark 1: ty Time (mean ± σ): 69.5 ms ± 1.6 ms [User: 530.8 ms, System: 34.8 ms] Range (min … max): 65.7 ms … 73.6 ms 40 runs Warning: Ignoring non-zero exit code. Benchmark 2: Pyrefly Time (mean ± σ): 128.3 ms ± 2.5 ms [User: 465.1 ms, System: 53.0 ms] Range (min … max): 123.4 ms … 134.3 ms 23 runs Warning: Ignoring non-zero exit code. Benchmark 3: mypy Time (mean ± σ): 1.316 s ± 0.012 s [User: 1.216 s, System: 0.092 s] Range (min … max): 1.303 s … 1.336 s 10 runs Benchmark 4: Pyright Time (mean ± σ): 1.420 s ± 0.010 s [User: 18.088 s, System: 0.981 s] Range (min … max): 1.404 s … 1.433 s 10 runs Warning: Ignoring non-zero exit code. Summary ty ran 1.85 ± 0.06 times faster than Pyrefly 18.94 ± 0.46 times faster than mypy 20.45 ± 0.49 times faster than Pyright可以看到,该输出中还包含User(用户态 CPU 时间)与System(内核态 CPU 时间)信息。值得注意的细节是:Pyright 的User时间(如 black 中的 18.088 s)远超其墙钟时间(1.420 s),说明其大量工作由并行/后台进程完成;而 ty 的User时间(530.8 ms)与墙钟时间(69.5 ms)的比例相对更接近,反映了其 CPU 调度特征与 Pyright 存在本质差异。
全部项目结果汇总
将文档中 9 个项目的 CLI 均值与加速比整理如下(均值均为mean ± σ,σ 为标准差):
| 项目 | ty | Pyrefly | mypy | Pyright | ty vs Pyrefly | ty vs mypy | ty vs Pyright |
|---|---|---|---|---|---|---|---|
| black | 69.5 ms ± 1.6 | 128.3 ms ± 2.5 | 1.316 s ± 0.012 | 1.420 s ± 0.010 | 1.85× | 18.94× | 20.45× |
| discord.py | 144.1 ms ± 4.9 | 193.4 ms ± 5.0 | 2.538 s ± 0.024 | 3.556 s ± 0.061 | 1.34× | 17.61× | 24.68× |
| homeassistant | 1.812 s ± 0.033 | 2.550 s ± 0.039 | 24.601 s ± 0.141 | 23.410 s ± 0.483 | 1.41× | 13.57× | 12.92× |
| isort | 82.3 ms ± 1.6 | 109.6 ms ± 1.5 | 679.4 ms ± 10.6 | 2.240 s ± 0.012 | 1.33× | 8.26× | 27.22× |
| jinja | 69.5 ms ± 1.4 | 105.0 ms ± 1.9 | 762.7 ms ± 6.4 | 1.324 s ± 0.014 | 1.51× | 10.97× | 19.05× |
| pandas | 428.0 ms ± 18.0 | 752.5 ms ± 15.4 | 13.089 s ± 0.041 | 7.512 s ± 0.076 | 1.76× | 30.58× | 17.55× |
| pandas-stubs | 94.4 ms ± 3.3 | 205.9 ms ± 1.9 | 6.971 s ± 0.080 | 2.201 s ± 0.013 | 2.18× | 73.86× | 23.32× |
| prefect | 113.1 ms ± 4.8 | 242.0 ms ± 8.8 | 701.4 ms ± 10.3 | 4.208 s ± 0.040 | 2.14× | 6.20× | 37.22× |
| pytorch | 1.216 s ± 0.042 | 1.492 s ± 0.025 | 28.227 s ± 0.074 | 16.885 s ± 0.505 | 1.23× | 23.22× | 13.89× |
注:homeassistant 一行的加速比顺序为
ty vs Pyrefly、ty vs Pyright、ty vs mypy(原始文档中该项目的 Summary 顺序为 Pyrefly → Pyright → mypy),表中已按统一列序排列,数值均来自原文。
数据解读要点
从上述数据可以观察出几个一致的模式:
- ty 在所有 9 个项目上均快于全部三个对比工具,对 Pyrefly 的领先幅度在 1.23×(pytorch)到 2.18×(pandas-stubs)之间。
- 对 mypy 与 Pyright 的领先幅度随项目规模与特性剧烈波动:在类型标注密度极高、stub 文件繁多的 pandas-stubs 上,ty 相对 mypy 达到73.86×;而在小型的 isort 上相对 mypy 为 8.26×。
- 大型项目上的绝对收益最显著:homeassistant 的 mypy 需 24.601 s、Pyright 需 23.410 s,而 ty 仅需 1.812 s——意味着一次完整的 CI 类型检查可以从"半分钟量级"压缩到"亚两秒量级";pytorch 上 mypy 需要 28.227 s,ty 仅 1.216 s。
- 标准差(σ)整体较小,说明各工具在重复运行下表现稳定;pandas-stubs 的 mypy 结果被标记为"检测到统计离群值,建议在安静的系统上重跑",这是唯一出现该提示的条目。
如何自行复现 CLI 基准
ty 的 CLI 基准本质上就是一次无缓存的完整类型检查。你可以在任何项目上快速体验 ty 的全量检查耗时,使用 uvx 免安装运行:
uvx ty check默认会检查工作目录或项目根目录下的所有 Python 文件(见 docs/index.md)。更细粒度的控制可参考 CLI 参考文档:ty check支持--exclude(gitignore 风格排除模式,如tests/、**/__pycache__/**)、--config-file(指定ty.toml配置文件路径,也可通过TY_CONFIG_FILE环境变量设置)、--color(控制彩色输出:auto/always/never)等选项,可用于构造与官方基准一致的检查范围与输出行为。
需要特别说明:官方基准的完整复现脚本(含项目拉取、工具安装、对比编排)由原文档指向ty_benchmark/README.md,而当前仓库(ruff/ 子模块尚未包含该脚本)内并不存在可直接执行的基准脚本,因此本文不提供逐行复现步骤,仅还原官方文档已公布的数据与方法。
LSP 基准测试:编辑器内交互的核心指标
对于语言服务器而言,单次全量检查的速度并非唯一指标——开发者在编辑器中更关心每次击键/保存后的响应延迟。BENCHMARKS.md 的 LSP 部分使用 pytest-benchmark 输出,覆盖两个典型场景,每个测试运行 10 轮(Rounds)、每轮 1 次迭代(Iterations)。表格中各列含义:Min/Max/Mean/Median(毫秒)、StdDev(标准差)、IQR(四分位距)、Outliers(离群值,格式高值;低值)、OPS(每秒操作数,括号内为相对 ty 的比值)。
场景一:增量编辑(Incremental edit)
该场景模拟在编辑器中打开文件并做小幅修改后,服务器完成一次增量重新分析所需的时间。原始输出示例(black):
Name (time in ms) Min Max Mean StdDev Median IQR Outliers OPS Rounds Iterations test_incremental_edit[black-ty] 13.5952 (1.0) 14.7028 (1.0) 14.0826 (1.0) 0.3919 (1.0) 13.9682 (1.0) 0.4927 (1.0) 4;0 71.0096 (1.0) 10 1 test_incremental_edit[black-pyrefly] 71.4268 (5.25) 99.0502 (6.74) 85.6680 (6.08) 7.9382 (20.25) 84.9140 (6.08) 12.2150 (24.79) 2;0 11.6730 (0.16) 10 1 test_incremental_edit[black-pyright] 475.1242 (34.95) 492.5708 (33.50) 483.2225 (34.31) 4.7892 (12.22) 483.9335 (34.65) 4.6348 (9.41) 3;1 2.0694 (0.03) 10 1全部项目均值汇总(单位:ms):
| 项目 | ty | Pyrefly | Pyright | ty 相对 Pyrefly | ty 相对 Pyright |
|---|---|---|---|---|---|
| black | 14.08 | 85.67 | 483.22 | 6.08× | 34.31× |
| discord.py | 18.99 | 86.52 | 504.86 | 4.56× | 26.59× |
| homeassistant | 27.32 | 86.96 | 565.54 | 3.18× | 20.70× |
| isort | 21.53 | 51.77 | 418.88 | 2.40× | 19.45× |
| jinja | 16.00 | 73.74 | 495.64 | 4.61× | 30.97× |
| pandas | 57.91 | 231.22 | 612.20 | 3.99× | 10.57× |
| prefect | 6.82 | 57.13 | 642.57 | 8.37× | 94.18× |
| pytorch | 3.78 | 26.45 | 408.11 | 7.00× | 107.97× |
增量编辑场景的亮点数据:在 prefect 上 ty 均值仅6.82 ms,在 pytorch 上仅3.78 ms,而 Pyright 在同样的编辑操作上分别需要 642.57 ms 与 408.11 ms——这意味着在 Pyright 中等待诊断反馈的时间内,ty 理论上可以完成上百次增量更新。这一表现与 README.md 中强调的"fine-grained incremental analysis(细粒度增量分析)"设计目标直接对应:ty 的 LSP 被专门设计为在 IDE 中编辑文件时提供快速更新,而非每次整体重算。
场景二:获取诊断(Fetch diagnostics)
该场景模拟文件首次打开或保存后,服务器计算并返回全部诊断信息(包括类型错误、提示等)的耗时。原始输出示例(black):
test_fetch_diagnostics[black-ty] 50.0127 (1.0) 52.7542 (1.0) 50.6750 (1.0) 0.8323 (1.51) 50.3874 (1.0) 0.9849 (1.30) 1;1 19.7336 (1.0) 10 1 test_fetch_diagnostics[black-pyrefly] 154.9342 (3.10) 156.7015 (2.97) 156.0514 (3.08) 0.5507 (1.0) 156.2235 (3.10) 0.7576 (1.0) 2;0 6.4081 (0.32) 10 1 test_fetch_diagnostics[black-pyright] 303.7652 (6.07) 310.5299 (5.89) 307.0854 (6.06) 1.7936 (3.26) 306.9718 (6.09) 1.8720 (2.47) 2;0 3.2564 (0.17) 10 1全部项目均值汇总(单位:ms):
| 项目 | ty | Pyrefly | Pyright | ty 相对 Pyrefly | ty 相对 Pyright |
|---|---|---|---|---|---|
| black | 50.68 | 156.05 | 307.09 | 3.08× | 6.06× |
| discord.py | 98.39 | 193.76 | 615.50 | 1.97× | 6.26× |
| homeassistant | 84.92 | 191.18 | 1222.58 | 2.25× | 14.40× |
| isort | 47.74 | 104.59 | 384.70 | 2.19× | 8.06× |
| jinja | 55.15 | 126.55 | 391.84 | 2.29× | 7.11× |
| pandas | 359.89 | 543.94 | 1902.71 | 1.51× | 5.29× |
| prefect | 157.44 | 420.96 | 1071.26 | 2.67× | 6.80× |
| pytorch | 52.05 | 134.94 | 683.31 | 2.59× | 13.13× |
获取诊断场景同样呈现一致的优势:ty 在 homeassistant 上仅需 84.92 ms,而 Pyright 需要 1,222.58 ms(约 14.4×);即便在最大的 pandas 项目上,ty 也以 359.89 ms 远低于 Pyright 的 1,902.71 ms。值得注意的是,该场景中 Pyrefly 与 ty 的差距(1.51×–3.08×)明显小于 Pyright 与 ty 的差距(5.29×–14.40×)。
两个 LSP 场景的工程含义
将两组 LSP 数据放在一起看,可以得出一个更完整的结论:
- 增量编辑考验的是"细粒度增量分析"能力——ty 的均值始终低于 60 ms(除 pandas 的 57.91 ms 外均在 30 ms 以下),达到了可感知的即时反馈水平;
- 获取诊断考验的是"全量产出诊断"的能力——ty 在所有项目上均优于对比工具,且随着项目变大(如 homeassistant、pandas、pytorch),相对 Pyright 的优势反而扩大。
这解释了 docs/features/language-server.md 与 README.md 中所述设计目标:ty 的 LSP 提供代码导航、补全、代码操作、自动导入、inlay hints、悬停帮助等完整能力(对应 语言服务器文档),而基准数据表明这些能力建立在足够快的增量与诊断计算之上。若要体验这些能力,可参阅 编辑器集成指南(支持 VS Code、PyCharm、Neovim 等)或直接运行ty server启动语言服务器(见 CLI 参考文档)。
解读基准数据的正确姿势:方法与局限
官方文档在给出数据的同时,也隐含了若干必须注意的解读边界:
- 单一硬件平台:全部数据来自 macOS Apple M3 Max(16 核 / 128 GB)。原文档明确提示"基准性能可能因操作系统而异,并因项目而异",因此这些数字不能直接外推到 Windows、Linux 或 x86 平台,也不应被视为跨平台的绝对结论。
- 特定版本快照:数据对应当前文档记录的版本组合(ty 0.0.55 / Pyrefly 1.1.1 / Pyright 1.1.410 / mypy 2.1.0)。工具版本迭代后结果会变化;ty 当前采用
0.0.x版本策略、API 尚不稳定(见 README.md 的版本策略说明),新旧版本之间可能发生性能与行为变化。 - 无缓存前提:README 中用于展示的 CLI 图表明确标注"without caching",本基准同样反映的是冷启动全量检查性能;在开启缓存或增量状态后,不同工具的相对表现可能进一步变化。
- 输出中的警告不影响计时:
Warning: Ignoring non-zero exit code与统计离群值提示(如 pandas-stubs 的 mypy)均为计时过程中的提示,前者源于退出码、后者建议在无干扰的系统上复测,二者都不否定计时均值本身。 - 代表性样本:9 个项目的选择覆盖了 Web、数据科学、ML 框架、stub 包、配置类库等典型形态,但"代表真实世界"不意味着"覆盖所有场景"——对于与你自身代码库结构差异较大的项目,建议以本仓库数据为参考,在目标环境上自行测量。
总结
BENCHMARKS.md 提供了一份结构完整、方法透明的官方基准:在 macOS M3 Max 平台上,ty 0.0.55 于全部 9 个测试项目的 CLI 全量检查中均显著快于 Pyrefly、mypy 与 Pyright(相对 mypy 最高达 73.86×,相对 Pyright 最高达 37.22×);在 LSP 场景中,ty 的增量编辑均值最低可至 3.78 ms(pytorch),获取诊断相对 Pyright 的优势在大型项目上普遍超过一个数量级。这些数字与 ty 在 README.md 中宣称的设计目标(10x–100x 级别提速、面向编辑器的细粒度增量分析)相互印证,为评估 ty 是否适合引入你的项目(无论是 CI 中的全量检查,还是编辑器内的交互式体验)提供了第一手的量化依据。
【免费下载链接】tyAn extremely fast Python type checker and language server, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ty2/ty
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考