Ruff 性能解密:为何它能比传统 Python Linter 快 100 倍

Ruff Performance Decoded: Why It Is 100x Faster Than Traditional Python Linters

| iDev Engineering | 2026-09-02T01:02:50

Ruff 以 Rust 重写 Python 代码检查工具,性能碾压 Flake8、Pylint 等传统方案。本文从编译器原理视角深入剖析 Ruff 的性能秘密。

Ruff rewrites Python linting tools in Rust, dramatically outperforming Flake8 and Pylint. This article analyzes Ruff's performance secrets from a compiler theory perspective.

Ruff 性能概览Ruff 由 Charlie Marsh 创建,目前由 Astral 团队维护,是一个用 Rust 编写的极速 Python Linter 和代码格式化器。在 CPython 代码库(约 60 万行 Python 代码)上的基准测试中,Ruff 完成全量检查仅需 0.3 秒,而 Flake8 需要 12 秒,Pylint 需要 90 秒以上。这种 100 倍以上的性能差距从何而来?解析器优化Ruff 使用自研的 Python 解析器(已独立为 RustPython Parser),相比基于 Python 的 ast 模块,Rust 解析器在词法分析和语法树构建阶段就已经快了约 20 倍。更关键的是,Ruff 的解析器生成的 AST 采用扁平化的 arena 分配策略,所有节点存储在连续内存中,极大地提升了 CPU 缓存命中率。规则执行引擎传统 Linter 通常为每条规则独立遍历 AST,而 Ruff 将所有启用的规则合并为单次遍历。它在 AST 遍历过程中维护一个状态机,根据当前节点类型动态分发到对应的规则检查函数。这意味着无论启用了 100 条还是 700 条规则,AST 遍历次数始终为 1 次。此外,Ruff 大量使用 Rust 的零成本抽象特性,规则检查函数在编译时就被内联优化。并行化与增量检查Ruff 在文件级别实现了并行检查,使用 rayon 工作窃取线程池充分利用多核 CPU。配合文件哈希缓存机制,二次检查只需要处理有变更的文件。在我们的项目中,保存文件后 Ruff 反馈几乎是即时的,真正实现了编辑器级别的实时代码检查体验。


Ruff Performance OverviewCreated by Charlie Marsh and maintained by the Astral team, Ruff is a blazing-fast Python linter and code formatter written in Rust. On the CPython codebase (approximately 600,000 lines of Python), Ruff completes a full check in just 0.3 seconds, compared to 12 seconds for Flake8 and over 90 seconds for Pylint. Where does this 100x-plus performance gap come from?Parser OptimizationsRuff uses a custom Python parser (now independent as RustPython Parser). Compared to Python's ast module, the Rust parser is already roughly 20x faster at lexical analysis and syntax tree construction. More critically, Ruff's parser generates ASTs using a flattened arena allocation strategy, storing all nodes in contiguous memory for dramatically improved CPU cache hit rates.Rule Execution EngineTraditional linters typically traverse the AST independently for each rule, but Ruff merges all enabled rules into a single traversal. It maintains a state machine during AST traversal, dynamically dispatching to corresponding rule check functions based on current node type. This means whether 100 or 700 rules are enabled, AST traversal occurs exactly once. Additionally, Ruff leverages Rust's zero-cost abstractions extensively, with rule check functions inlined at compile time.Parallelization and Incremental CheckingRuff implements file-level parallel checking using rayon's work-stealing thread pool to fully utilize multi-core CPUs. Combined with file hash caching, subsequent checks only process changed files. In our projects, Ruff feedback after saving a file is nearly instantaneous, delivering true editor-level real-time code checking.

← Back to News