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

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

Merged
merged 1 commit into from
Aug 8, 2024

Conversation

cclauss
Copy link
Contributor

@cclauss cclauss commented Aug 8, 2024

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):

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.

> ~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.
Copy link

codspeed-hq bot commented Aug 8, 2024

CodSpeed Performance Report

Merging #12746 will degrade performances by 6.3%

Comparing cclauss:patch-1 (8fbf9d1) with main (6d9205e)

Summary

⚡ 1 improvements
❌ 1 regressions
✅ 30 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark main cclauss:patch-1 Change
linter/all-rules[numpy/globals.py] 725.1 µs 773.8 µs -6.3%
linter/default-rules[pydantic/types.py] 1.9 ms 1.8 ms +4.12%

Copy link
Contributor

github-actions bot commented Aug 8, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@cclauss cclauss changed the title SIM110: any() is ~3x less performant than the code it replaces SIM110: any() is ~3x slower than the code it replaces Aug 8, 2024
@charliermarsh charliermarsh merged commit 33e9a6a into astral-sh:main Aug 8, 2024
19 of 20 checks passed
@charliermarsh charliermarsh added the documentation Improvements or additions to documentation label Aug 8, 2024
@cclauss cclauss deleted the patch-1 branch August 8, 2024 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants