Skip to content

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

Merged
charliermarsh merged 1 commit into
astral-sh:mainfrom
cclauss:patch-1
Aug 8, 2024
Merged

SIM110: any() is ~3x slower than the code it replaces#12746
charliermarsh merged 1 commit into
astral-sh:mainfrom
cclauss:patch-1

Conversation

@cclauss

@cclauss cclauss commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

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.
@codspeed-hq

codspeed-hq Bot commented Aug 8, 2024

Copy link
Copy Markdown

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%

@github-actions

github-actions Bot commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

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
@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