Talk notes
- Benchmark source code
- PEP684 - A Per-Interpreter GIL
- PEP554 - Multiple interpreters in the Standard Library
- Extrainterpreters project
These are the code samples used in the talk
import numpy
# Create a random array of 100,000 integers between 0 and 100
a = numpy.random.randint(0, 100, 100_000)
for x in a:
abs(x - 50)
Benchmark comparison -
import numpy
import threading
# Create a random array of 100,000 integers between 0 and 100
a = numpy.random.randint(0, 100, 100_000)
def simple_abs_range(vec):
for x in vec:
abs(x - 50)
def f_linear():
# Calculate the distance for each value to 50
simple_abs_range(a)
def f_threaded():
threads = []
# Split array into blocks of 100 and start a thread for each
for ar in numpy.split(a, 100):
t = threading.Thread(target=simple_abs_range, args=(ar,))
t.start()
threads.append(t)
for t in threads:
t.join()
import _xxsubinterpreters as interpreters
interpreters.run('''
print("Hello World")
''')
Non-blocking example:
from threading import Thread
import _xxsubinterpreters as interpreters
t = Thread(target=interpreters.run, args=("print('hello world')",))
t.start()
import interpreters
def f():
print('hello world’)
import things
things.do_stuff()
interpreters.run(f)
def f(x):
...
with interpreters.PoolExecutor(interpreters=4) as pool:
# Map a sequence of calls to interpreters
pool.map(f, [1, 2, 3, ...])
# or run a single task
pool.submit(f, 1)