Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark all rules #3570

Merged
merged 2 commits into from Mar 17, 2023
Merged

Benchmark all rules #3570

merged 2 commits into from Mar 17, 2023

Conversation

MichaReiser
Copy link
Member

@MichaReiser MichaReiser commented Mar 17, 2023

Summary

This PR adds the new benchmark group linter/all-rules (and renames the existing group to linter/default-rules).

The motivation of benchmarking all rules is new rules are not part of the default-set and are, thus, not benchmarked. This can result in us missing a new rule that regresses the performance for all users enabling it.

Considerations

Why not change the existing benchmark to run all rules: The default rules benchmark allows us to track the performance of Ruff's infrastructure better. The cost of our infrastructure (scope analysis, traversing the tree) is neglectable when running all rules but is more significant when only running some rules. At least now, the cost of running some more benchmarks is "cheap" because the CI job spends most time building the benchmark.

@MichaReiser MichaReiser marked this pull request as ready for review March 17, 2023 07:12
@MichaReiser MichaReiser changed the title benchmarks: Benchmark all rules Benchmark all rules Mar 17, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
linter/all-rules/large/dataset.py                                                 1.00     14.5±0.06ms     2.8 MB/sec
linter/all-rules/numpy/ctypeslib.py                                               1.00      3.8±0.02ms     4.3 MB/sec
linter/all-rules/numpy/globals.py                                                 1.00    436.3±1.57µs     6.8 MB/sec
linter/all-rules/pydantic/types.py                                                1.00      6.4±0.01ms     4.0 MB/sec
linter/default-rules/large/dataset.py                                             1.00      8.2±0.01ms     5.0 MB/sec
linter/default-rules/numpy/ctypeslib.py                                           1.00   1781.3±3.16µs     9.3 MB/sec
linter/default-rules/numpy/globals.py                                             1.00    186.3±0.56µs    15.8 MB/sec
linter/default-rules/pydantic/types.py                                            1.00      3.8±0.01ms     6.7 MB/sec
linter/large/dataset.py                    1.00      8.3±0.01ms     4.9 MB/sec  
linter/numpy/ctypeslib.py                  1.00      2.2±0.01ms   156.8 MB/sec  
linter/numpy/globals.py                    1.00  1146.0±10.33µs   155.5 MB/sec  
linter/pydantic/types.py                   1.00      3.9±0.02ms     6.6 MB/sec  

Windows

group                                      main                                    pr
-----                                      ----                                    --
linter/all-rules/large/dataset.py                                                  1.00     20.1±1.17ms     2.0 MB/sec
linter/all-rules/numpy/ctypeslib.py                                                1.00      5.3±0.21ms     3.1 MB/sec
linter/all-rules/numpy/globals.py                                                  1.00   687.8±45.59µs     4.3 MB/sec
linter/all-rules/pydantic/types.py                                                 1.00      9.0±0.41ms     2.8 MB/sec
linter/default-rules/large/dataset.py                                              1.00     11.5±0.41ms     3.5 MB/sec
linter/default-rules/numpy/ctypeslib.py                                            1.00      2.4±0.10ms     7.0 MB/sec
linter/default-rules/numpy/globals.py                                              1.00   295.0±19.57µs    10.0 MB/sec
linter/default-rules/pydantic/types.py                                             1.00      5.2±0.31ms     4.9 MB/sec
linter/large/dataset.py                    1.00     12.4±0.68ms     3.3 MB/sec   
linter/numpy/ctypeslib.py                  1.00      2.7±0.13ms   126.4 MB/sec   
linter/numpy/globals.py                    1.00  1441.7±116.37µs   123.6 MB/sec  
linter/pydantic/types.py                   1.00      5.4±0.27ms     4.7 MB/sec   

Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're doubling the number of output rows, should we consider reducing the number of files that are included in the benchmark, just to keep it information-dense? (In other words, how much marginal benefit is there right now for each of the four files we're analyzing? Are any of them redundant?)

@MichaReiser
Copy link
Member Author

The output will have 8 rows after merging (the last 4 are only because the benchmark names between main and this branch don't match).

Since we're doubling the number of output rows, should we consider reducing the number of files that are included in the benchmark, just to keep it information-dense? (In other words, how much marginal benefit is there right now for each of the four files we're analyzing? Are any of them redundant?)

We could. I didn't spend much time picking the files but my thinking was:

  • a small file -> sensitive to changes that increase the infrastructure overhead: numpy/globals
  • two medium files -> to represent the average case: [pydantic/types, nmpy/ctypeslib.py]
  • a large file -> sensitive to rules with O(n^2) or worse complexity: [large/dataset.py]
  • a file with many type annotations pydantic/types

We could potentially remove numpy/ctypeslib.py because it is a medium file but I think it's good worth keeping it because the large file has barely any comments.

@MichaReiser
Copy link
Member Author

Current dependencies on/for this PR:

This comment was auto-generated by Graphite.

)?),
TestCase::normal(TestFile::try_download("numpy/ctypeslib.py", "https://github.com/numpy/numpy/blob/main/numpy/ctypeslib.py")?),
TestCase::normal(TestFile::try_download("numpy/ctypeslib.py", "https://raw.githubusercontent.com/numpy/numpy/e42c9503a14d66adfd41356ef5640c6975c45218/numpy/ctypeslib.py")?),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops... I never verified if it downloads the correct files. The non-raw endpoints return HTML and not python 🤭

@@ -68,6 +69,28 @@ pub struct TestFile {
code: String,
}

static TARGET_DIR: once_cell::sync::Lazy<PathBuf> = once_cell::sync::Lazy::new(|| {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes an issue where the benchmarks created a target folder in the ruff_benchmark directory instead of re-using Cargo's target directory (copied from criterion)

@MichaReiser MichaReiser merged commit 87fab4a into main Mar 17, 2023
12 checks passed
@MichaReiser MichaReiser deleted the benchmark-all-rules branch March 17, 2023 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants