BlogDocs

SIM110: `any()` is ~3x slower than the code it replaces(#12746)

Merged
Merging
cclauss:patch-1
(
8fbf9d1
) into
main
(
6d9205e
)
-6%
IMPROVEMENTS
1
REGRESSIONS
1
UNTOUCHED
30
NEW
0
DROPPED
0
IGNORED
0

Benchmarks

Failed

linter/all-rules[numpy/globals.py]Regression
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules::linter/all-rules[numpy/globals.py]
-6%
725.1 µs
773.8 µs

Improved

linter/default-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules::linter/default-rules[pydantic/types.py]
+4%
1.9 ms
1.8 ms

Passed

linter/all-with-preview-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules::linter/all-with-preview-rules[numpy/ctypeslib.py]
+1%
4.9 ms
4.9 ms
linter/all-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules::linter/all-rules[large/dataset.py]
+1%
16.5 ms
16.4 ms
linter/default-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules::linter/default-rules[numpy/ctypeslib.py]
+1%
919.8 µs
914.8 µs
linter/default-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules::linter/default-rules[large/dataset.py]
0%
3.7 ms
3.6 ms
linter/all-with-preview-rules[numpy/globals.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules::linter/all-with-preview-rules[numpy/globals.py]
0%
813.6 µs
813 µs
linter/all-with-preview-rules[large/dataset.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules::linter/all-with-preview-rules[large/dataset.py]
0%
19.2 ms
19.2 ms
formatter[large/dataset.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter::formatter[large/dataset.py]
0%
9.3 ms
9.3 ms
parser[unicode/pypinyin.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser::parser[unicode/pypinyin.py]
0%
309.9 µs
309.9 µs
parser[large/dataset.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser::parser[large/dataset.py]
0%
4.9 ms
4.9 ms
lexer[large/dataset.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer::lexer[large/dataset.py]
0%
1.1 ms
1.1 ms
lexer[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer::lexer[numpy/ctypeslib.py]
0%
216.3 µs
216.3 µs
lexer[numpy/globals.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer::lexer[numpy/globals.py]
0%
29 µs
29 µs
lexer[pydantic/types.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer::lexer[pydantic/types.py]
0%
481.6 µs
481.6 µs
lexer[unicode/pypinyin.py]
crates/ruff_benchmark/benches/lexer.rs::lexer::benchmark_lexer::lexer[unicode/pypinyin.py]
0%
74 µs
74 µs
parser[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser::parser[numpy/ctypeslib.py]
0%
913.1 µs
913.1 µs
formatter[pydantic/types.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter::formatter[pydantic/types.py]
0%
3.5 ms
3.5 ms
formatter[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter::formatter[numpy/ctypeslib.py]
0%
1.8 ms
1.8 ms
parser[numpy/globals.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser::parser[numpy/globals.py]
0%
102 µs
102 µs
parser[pydantic/types.py]
crates/ruff_benchmark/benches/parser.rs::parser::benchmark_parser::parser[pydantic/types.py]
0%
2 ms
2 ms
formatter[numpy/globals.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter::formatter[numpy/globals.py]
0%
240.1 µs
240.1 µs
formatter[unicode/pypinyin.py]
crates/ruff_benchmark/benches/formatter.rs::formatter::benchmark_formatter::formatter[unicode/pypinyin.py]
0%
649.6 µs
649.6 µs
linter/all-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules::linter/all-rules[unicode/pypinyin.py]
0%
2.2 ms
2.2 ms
linter/default-rules[numpy/globals.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules::linter/default-rules[numpy/globals.py]
0%
188.1 µs
188.2 µs
linter/default-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::default_rules::benchmark_default_rules::linter/default-rules[unicode/pypinyin.py]
0%
349.5 µs
350.2 µs
red_knot_check_file[cold]
crates/ruff_benchmark/benches/red_knot.rs::check_file::benchmark_cold::red_knot_check_file[cold]
0%
38.4 ms
38.5 ms
linter/all-with-preview-rules[unicode/pypinyin.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules::linter/all-with-preview-rules[unicode/pypinyin.py]
0%
2.5 ms
2.5 ms
linter/all-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules::linter/all-rules[pydantic/types.py]
0%
8 ms
8.1 ms
linter/all-with-preview-rules[pydantic/types.py]
crates/ruff_benchmark/benches/linter.rs::preview_rules::benchmark_preview_rules::linter/all-with-preview-rules[pydantic/types.py]
0%
9.7 ms
9.7 ms
linter/all-rules[numpy/ctypeslib.py]
crates/ruff_benchmark/benches/linter.rs::all_rules::benchmark_all_rules::linter/all-rules[numpy/ctypeslib.py]
0%
4.1 ms
4.1 ms
red_knot_check_file[incremental]
crates/ruff_benchmark/benches/red_knot.rs::check_file::benchmark_incremental::red_knot_check_file[incremental]
-1%
1.6 ms
1.6 ms

Commits

Click on a commit to change the comparison range
base
main
6d9205e
-6%
SIM110: `any()` is ~3x less performant than the code it replaces > ~Builtins are also more efficient than `for` loops.~ Let's not promise performance because this code transformation does not deliver. Benchmark written by @dcbaker > `any()` seems to be about 1/3 as fast (Python 3.11.9, NixOS): ```python loop = 'abcdef'.split() found = 'f' nfound = 'g' def test1(): for x in loop: if x == found: return True return False def test2(): return any(x == found for x in loop) def test3(): for x in loop: if x == nfound: return True return False def test4(): return any(x == nfound for x in loop) if __name__ == "__main__": import timeit print('for loop (found) :', timeit.timeit(test1)) print('for loop (not found):', timeit.timeit(test3)) print('any() (found) :', timeit.timeit(test2)) print('any() (not found) :', timeit.timeit(test4)) ``` ``` for loop (found) : 0.051076093994197436 for loop (not found): 0.04388196699437685 any() (found) : 0.15422860698890872 any() (not found) : 0.15568504799739458 ``` I have retested with longer lists and on multiple Python versions with similar results.
8fbf9d1
1 month ago
by cclauss
ResourcesHomePricingDocsBlogGitHubChangelog
Copyright © 2024 CodSpeed Technology SAS. All rights reserved.