1. 23 Feb, 2018 9 commits
    • Jason Madden's avatar
    • Jason Madden's avatar
      Use new cython on Windows too. · accd9cf6
      Jason Madden authored
      accd9cf6
    • Jason Madden's avatar
      Honor PURE_PYTHON at runtime. · 647918f7
      Jason Madden authored
      Fixes #1118.
      
      Also some speed improvements for semaphores.
      647918f7
    • Jason Madden's avatar
      Merge pull request #1117 from gevent/faster-locals · cfea657f
      Jason Madden authored
      Speed up gevent.local.local more, especially for subclasses (2-3x faster)
      cfea657f
    • Jason Madden's avatar
      Add link to pr #1117. [skip ci] · c6458a80
      Jason Madden authored
      c6458a80
    • Jason Madden's avatar
      Speed of gevent.local.local more, especially for subclasses (2-3x faster) · b1125a79
      Jason Madden authored
      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%) |
      +--------------------+-------------------+-----------------------------+
      b1125a79
    • Jason Madden's avatar
      Add a script for benchmarking gevent.local · d9602bf8
      Jason Madden authored
      [skip ci]
      Current numbers:
      
      local_36_master
      ===============
      
      getattr gevent: Mean +- std dev: 216 ns +- 6 ns
      setattr gevent: Mean +- std dev: 215 ns +- 6 ns
      getattr gevent sub: Mean +- std dev: 600 ns +- 19 ns
      setattr gevent sub: Mean +- std dev: 591 ns +- 38 ns
      getattr native: Mean +- std dev: 56.9 ns +- 4.1 ns
      setattr native: Mean +- std dev: 84.3 ns +- 4.9 ns
      getattr native sub: Mean +- std dev: 65.6 ns +- 5.3 ns
      setattr native sub: Mean +- std dev: 76.2 ns +- 4.6 ns
      
      local_27_master
      ===============
      
      getattr gevent: Mean +- std dev: 177 ns +- 7 ns
      setattr gevent: Mean +- std dev: 192 ns +- 6 ns
      getattr gevent sub: Mean +- std dev: 501 ns +- 10 ns
      setattr gevent sub: Mean +- std dev: 536 ns +- 25 ns
      getattr native: Mean +- std dev: 93.8 ns +- 3.6 ns
      setattr native: Mean +- std dev: 118 ns +- 6 ns
      getattr native sub: Mean +- std dev: 102 ns +- 4 ns
      setattr native sub: Mean +- std dev: 118 ns +- 8 ns
      
      local_pypy_master
      =================
      
      getattr gevent: Mean +- std dev: 135 ns +- 6 ns
      setattr gevent: Mean +- std dev: 126 ns +- 4 ns
      getattr gevent sub: Mean +- std dev: 150 ns +- 4 ns
      setattr gevent sub: Mean +- std dev: 153 ns +- 7 ns
      getattr native: Mean +- std dev: 0.18 ns +- 0.00 ns
      setattr native: Mean +- std dev: 0.18 ns +- 0.01 ns
      getattr native sub: Mean +- std dev: 0.18 ns +- 0.01 ns
      setattr native sub: Mean +- std dev: 0.19 ns +- 0.01 ns
      d9602bf8
    • Jason Madden's avatar
      Merge pull request #1116 from gevent/issue755 · 43e776b6
      Jason Madden authored
      Add Greenlet.minimal_ident, a small, sequential, reusable counter for greenlets
      43e776b6
    • Jason Madden's avatar
      Tweak changenote [skip ci] · 5af60cc7
      Jason Madden authored
      5af60cc7
  2. 22 Feb, 2018 10 commits
  3. 21 Feb, 2018 2 commits
    • Jason Madden's avatar
      Add spawn_tree_locals, spawning_greenlet and spawning_stack to Greenlet · 15fc1ecc
      Jason Madden authored
      Based on #755.
      
      A comment in the code goes into detail about the timing. Here it is
      again:
      
       Timings taken Feb 21 2018 prior to integration of #755
       python -m perf timeit -s 'import gevent' 'gevent.Greenlet()'
       3.6.4       : Mean +- std dev: 1.08 us +- 0.05 us
       2.7.14      : Mean +- std dev: 1.44 us +- 0.06 us
       PyPy2 5.10.0: Mean +- std dev: 2.14 ns +- 0.08 ns
      
       After the integration of spawning_stack, spawning_greenlet,
       and spawn_tree_locals on that same date:
       3.6.4       : Mean +- std dev: 8.92 us +- 0.36 us ->  8.2x
       2.7.14      : Mean +- std dev: 14.8 us +- 0.5 us  -> 10.2x
       PyPy2 5.10.0: Mean +- std dev: 3.24 us +- 0.17 us ->  1.5x
      
      Selected bench_spawn output on 3.6.4 before:
      
      //gevent36/bin/python src/greentest/bench_spawn.py eventlet --ignore-import-errors
      using eventlet from //gevent36/lib/python3.6/site-packages/eventlet/__init__.py
      spawning: 11.93 microseconds per greenlet
      sleep(0): 23.49 microseconds per greenlet
      
      //gevent36/bin/python src/greentest/bench_spawn.py gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 3.39 microseconds per greenlet
      sleep(0): 17.59 microseconds per greenlet
      
      //gevent36/bin/python src/greentest/bench_spawn.py geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 8.71 microseconds per greenlet
      
      //gevent36/bin/python src/greentest/bench_spawn.py geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 2.09 microseconds per greenlet
      
      //gevent36/bin/python src/greentest/bench_spawn.py none --ignore-import-errors
          noop: 0.33 microseconds per greenlet
      
      And after:
      
      //gevent36/bin/python bench_spawn.py gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 12.99 microseconds per greenlet -> 3.8x
      
      //gevent36/bin/python bench_spawn.py geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 19.49 microseconds per greenlet -> 2.2x
      
      //gevent36/bin/python bench_spawn.py geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 4.57 microseconds per greenlet -> 2.2x
      
      We're approximately the speed of eventlet now.
      
      Refs #755
      15fc1ecc
    • Jason Madden's avatar
      Update bench_spawn · 54ffea34
      Jason Madden authored
      Current numbers on my workstation:
      
      CPython 3.6.4
      
      //gevent36/bin/python bench_spawn.py eventlet --ignore-import-errors
      using eventlet from //python3.6/site-packages/eventlet/__init__.py
      spawning: 11.93 microseconds per greenlet
      sleep(0): 23.49 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 3.39 microseconds per greenlet
      sleep(0): 17.59 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 8.71 microseconds per greenlet
      sleep(0): 16.99 microseconds per greenlet
       joining: 7.34 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 2.09 microseconds per greenlet
      sleep(0): 13.57 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py none --ignore-import-errors
          noop: 0.33 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py --with-kwargs eventlet --ignore-import-errors
      using eventlet from //python3.6/site-packages/eventlet/__init__.py
      spawning: 12.06 microseconds per greenlet
      sleep(0): 24.25 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py --with-kwargs gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 4.62 microseconds per greenlet
      sleep(0): 22.18 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py --with-kwargs geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 10.25 microseconds per greenlet
      sleep(0): 18.89 microseconds per greenlet
       joining: 7.14 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py --with-kwargs geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 3.27 microseconds per greenlet
      sleep(0): 15.03 microseconds per greenlet
      
      //gevent36/bin/python bench_spawn.py --with-kwargs none --ignore-import-errors
          noop: 0.50 microseconds per greenlet
      
      CPython 2.7.14
      
      //gevent27/bin/python bench_spawn.py eventlet --ignore-import-errors
      using eventlet from //python2.7/site-packages/eventlet/__init__.pyc
      spawning: 17.84 microseconds per greenlet
      sleep(0): 31.42 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 4.95 microseconds per greenlet
      sleep(0): 21.40 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 12.44 microseconds per greenlet
      sleep(0): 22.90 microseconds per greenlet
       joining: 10.68 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 2.33 microseconds per greenlet
      sleep(0): 15.11 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py none --ignore-import-errors
          noop: 0.58 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py --with-kwargs eventlet --ignore-import-errors
      using eventlet from //python2.7/site-packages/eventlet/__init__.pyc
      spawning: 19.38 microseconds per greenlet
      sleep(0): 31.62 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py --with-kwargs gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 6.59 microseconds per greenlet
      sleep(0): 23.12 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py --with-kwargs geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 13.78 microseconds per greenlet
      sleep(0): 21.65 microseconds per greenlet
       joining: 10.86 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py --with-kwargs geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 3.59 microseconds per greenlet
      sleep(0): 16.14 microseconds per greenlet
      
      //gevent27/bin/python bench_spawn.py --with-kwargs none --ignore-import-errors
          noop: 0.65 microseconds per greenlet
      
      PyPy2 5.10.0
      
      //geventpypy/bin/python bench_spawn.py eventlet --ignore-import-errors
      using eventlet from //geventpypy/site-packages/eventlet/__init__.pyc
      spawning: 29.91 microseconds per greenlet
      sleep(0): 84.24 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.py
      spawning: 0.73 microseconds per greenlet
      sleep(0): 33.02 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 2.49 microseconds per greenlet
      sleep(0): 38.56 microseconds per greenlet
       joining: 13.08 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 0.52 microseconds per greenlet
      sleep(0): 29.63 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py none --ignore-import-errors
          noop: 0.02 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py --with-kwargs eventlet --ignore-import-errors
      using eventlet from //geventpypy/site-packages/eventlet/__init__.pyc
      spawning: 30.36 microseconds per greenlet
      sleep(0): 83.00 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py --with-kwargs gevent --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 1.56 microseconds per greenlet
      sleep(0): 34.80 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py --with-kwargs geventpool --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 3.48 microseconds per greenlet
      sleep(0): 39.43 microseconds per greenlet
       joining: 16.21 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py --with-kwargs geventraw --ignore-import-errors
      using gevent from //src/gevent/__init__.pyc
      spawning: 1.51 microseconds per greenlet
      sleep(0): 52.19 microseconds per greenlet
      
      //geventpypy/bin/python bench_spawn.py --with-kwargs none --ignore-import-errors
          noop: 0.13 microseconds per greenlet
      
      [skip ci]
      54ffea34
  4. 20 Feb, 2018 7 commits
  5. 19 Feb, 2018 6 commits
  6. 17 Feb, 2018 3 commits
  7. 16 Feb, 2018 3 commits