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

Speed of gevent.local.local more, especially for subclasses (2-3x faster) #1117

Merged
merged 2 commits into from Feb 23, 2018

Conversation

Projects
None yet
1 participant
@jamadden
Member

jamadden commented Feb 23, 2018

Do this with some cython tricks and some caching of type attributes.
Cython 0.28 compiles this code to be quite a bit faster than Cython
0.27 does (the below uses 0.28), but it's still a win on both.

The type caching could potentially be a compatibility issue, but in
practice I suspect it won't be.

Benchmarks on 3.6:

Benchmark 3.6 3.6 This Branch
getattr gevent 190 ns 158 ns: 1.20x faster (-17%)
setattr gevent 180 ns 165 ns: 1.09x faster (-8%)
getattr gevent sub 540 ns 175 ns: 3.09x faster (-68%)
setattr gevent sub 528 ns 179 ns: 2.95x faster (-66%)
setattr native 80.8 ns 78.8 ns: 1.03x faster (-2%)

Not significant (3): getattr native; getattr native sub; setattr native sub

Benchmarks on 2.7:

Benchmark local_27_master2 local_27_tweak2
getattr gevent 162 ns 158 ns: 1.03x faster (-3%)
setattr gevent 173 ns 165 ns: 1.04x faster (-4%)
getattr gevent sub 471 ns 181 ns: 2.61x faster (-62%)
setattr gevent sub 462 ns 190 ns: 2.44x faster (-59%)
getattr native 87.4 ns 89.7 ns: 1.03x slower (+3%)
setattr native 133 ns 110 ns: 1.20x faster (-17%)
getattr native sub 101 ns 97.9 ns: 1.03x faster (-3%)
setattr native sub 118 ns 111 ns: 1.06x faster (-6%)

PyPy unfortunately shows as a little slower, though I'm not sure I
fully believe that:

Benchmark local_pypy_master local_pypy_tweak2
getattr gevent 135 ns 157 ns: 1.16x slower (+16%)
setattr gevent 126 ns 162 ns: 1.28x slower (+28%)
getattr gevent sub 150 ns 175 ns: 1.17x slower (+17%)
setattr gevent sub 153 ns 183 ns: 1.20x slower (+20%)
getattr native 0.18 ns 0.19 ns: 1.05x slower (+5%)
setattr native 0.18 ns 0.20 ns: 1.06x slower (+6%)
getattr native sub 0.18 ns 0.19 ns: 1.05x slower (+5%)
setattr native sub 0.19 ns 0.18 ns: 1.06x faster (-6%)
Speed of gevent.local.local more, especially for subclasses (2-3x fas…
…ter)

Do this with some cython tricks and some caching of type attributes.
Cython 0.28 compiles this code to be quite a bit faster than Cython
0.27 does (the below uses 0.28), but it's still a win on both.

The type caching could potentially be a compatibility issue, but in
practice I suspect it won't be.

Benchmarks on 3.6:

+--------------------+------------------+-----------------------------+
| Benchmark          | 3.6              | 3.6 This Branch             |
+====================+==================+=============================+
| getattr gevent     | 190 ns           | 158 ns: 1.20x faster (-17%) |
+--------------------+------------------+-----------------------------+
| setattr gevent     | 180 ns           | 165 ns: 1.09x faster (-8%)  |
+--------------------+------------------+-----------------------------+
| getattr gevent sub | 540 ns           | 175 ns: 3.09x faster (-68%) |
+--------------------+------------------+-----------------------------+
| setattr gevent sub | 528 ns           | 179 ns: 2.95x faster (-66%) |
+--------------------+------------------+-----------------------------+
| setattr native     | 80.8 ns          | 78.8 ns: 1.03x faster (-2%) |
+--------------------+------------------+-----------------------------+

Not significant (3): getattr native; getattr native sub; setattr native sub

Benchmarks on 2.7:

+--------------------+------------------+-----------------------------+
| Benchmark          | local_27_master2 | local_27_tweak2             |
+====================+==================+=============================+
| getattr gevent     | 162 ns           | 158 ns: 1.03x faster (-3%)  |
+--------------------+------------------+-----------------------------+
| setattr gevent     | 173 ns           | 165 ns: 1.04x faster (-4%)  |
+--------------------+------------------+-----------------------------+
| getattr gevent sub | 471 ns           | 181 ns: 2.61x faster (-62%) |
+--------------------+------------------+-----------------------------+
| setattr gevent sub | 462 ns           | 190 ns: 2.44x faster (-59%) |
+--------------------+------------------+-----------------------------+
| getattr native     | 87.4 ns          | 89.7 ns: 1.03x slower (+3%) |
+--------------------+------------------+-----------------------------+
| setattr native     | 133 ns           | 110 ns: 1.20x faster (-17%) |
+--------------------+------------------+-----------------------------+
| getattr native sub | 101 ns           | 97.9 ns: 1.03x faster (-3%) |
+--------------------+------------------+-----------------------------+
| setattr native sub | 118 ns           | 111 ns: 1.06x faster (-6%)  |
+--------------------+------------------+-----------------------------+

PyPy unfortunately shows as a little slower, though I'm not sure I
fully believe that:

+--------------------+-------------------+-----------------------------+
| Benchmark          | local_pypy_master | local_pypy_tweak2           |
+====================+===================+=============================+
| getattr gevent     | 135 ns            | 157 ns: 1.16x slower (+16%) |
+--------------------+-------------------+-----------------------------+
| setattr gevent     | 126 ns            | 162 ns: 1.28x slower (+28%) |
+--------------------+-------------------+-----------------------------+
| getattr gevent sub | 150 ns            | 175 ns: 1.17x slower (+17%) |
+--------------------+-------------------+-----------------------------+
| setattr gevent sub | 153 ns            | 183 ns: 1.20x slower (+20%) |
+--------------------+-------------------+-----------------------------+
| getattr native     | 0.18 ns           | 0.19 ns: 1.05x slower (+5%) |
+--------------------+-------------------+-----------------------------+
| setattr native     | 0.18 ns           | 0.20 ns: 1.06x slower (+6%) |
+--------------------+-------------------+-----------------------------+
| getattr native sub | 0.18 ns           | 0.19 ns: 1.05x slower (+5%) |
+--------------------+-------------------+-----------------------------+
| setattr native sub | 0.19 ns           | 0.18 ns: 1.06x faster (-6%) |
+--------------------+-------------------+-----------------------------+
@jamadden

This comment has been minimized.

Member

jamadden commented Feb 23, 2018

For fun, here's a look at the difference compiling with Cython 0.28 makes. First, the code prior to this commit (the code in 1.3a1):

Benchmark lCython 0.27.3 Cython 0.28
getattr gevent 215 ns 190 ns: 1.13x faster (-11%)
setattr gevent 212 ns 180 ns: 1.18x faster (-15%)
getattr gevent sub 563 ns 540 ns: 1.04x faster (-4%)
setattr gevent sub 558 ns 528 ns: 1.06x faster (-5%)

For even more fun, let's look at the gevent 1.2.2 code (uncompiled) versus this branch with Cython 0.28:

Benchmark local_36_122 local_36_tweak2
getattr gevent 6.62 us 158 ns: 41.88x faster (-98%)
setattr gevent 7.27 us 165 ns: 44.15x faster (-98%)
getattr gevent sub 7.15 us 175 ns: 40.90x faster (-98%)
setattr gevent sub 7.06 us 179 ns: 39.45x faster (-97%)

@jamadden jamadden changed the title from Speed of gevent.local.local more, especially for subclasses (2-3x faser) to Speed of gevent.local.local more, especially for subclasses (2-3x faster) Feb 23, 2018

@jamadden jamadden merged commit cfea657 into master Feb 23, 2018

@jamadden jamadden deleted the faster-locals branch Feb 23, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment