vpype
vpype copied to clipboard
LineCollection: Parallelise Numpy operations
Most numpy operations release the GIL and are thus well suited for threaded parallelisation.
import random
import timeit
import matplotlib.pyplot as plt
from multiprocessing.dummy import Pool
import numpy as np
import vpype as vp
thread_pool = Pool()
random.seed(0)
N1 = 10000
dataset1 = [vp.circle(0, 0, random.uniform(100, 1000), 0.1) for _ in range(N1)]
def translate_basic(lc, c):
return [line + c for line in lc]
def translate_threaded(lc, c):
def _translate(line):
return line + c
return list(thread_pool.map(_translate, lc, chunksize=50))
offset = complex(150, 450)
iter_count = np.round(np.linspace(1, N1, 25)).astype(int)
times_basic = []
times_threaded = []
for n in iter_count:
times_basic.append(timeit.timeit(lambda:translate_basic(dataset1[:n], offset), number=20))
times_threaded.append(timeit.timeit(lambda: translate_threaded(dataset1[:n], offset), number=20))
thread_pool.close()
thread_pool.terminate()
plt.plot(iter_count, times_basic, '.-r')
plt.plot(iter_count, times_threaded, '.-b')
plt.show()
N2 = 50000
dataset2 = [vp.line(
random.uniform(0, 1000),
random.uniform(0, 1000),
random.uniform(0, 1000),
random.uniform(0, 1000),
) for _ in range(N2)]
import random
import timeit
import matplotlib.pyplot as plt
from multiprocessing.dummy import Pool
import numpy as np
thread_pool = Pool()
line_lengths = np.concatenate(
[np.arange(2, 2500, 50), np.arange(2500, 5000, 100), np.arange(5000, 10000, 200),
np.arange(10000, 20000, 500)])
random.seed(0)
N = 10000
def translate_basic(lc, c):
return [line + c for line in lc]
def translate_threaded(lc, c):
def _translate(line):
return line + c
return list(thread_pool.map(_translate, lc, chunksize=50))
offset = complex(150, 450)
times_basic = []
times_threaded = []
for line_length in line_lengths:
dataset1 = [np.empty(line_length, dtype=complex) for _ in range(N)]
for line in dataset1:
line.real = np.random.uniform(0, 1000, line_length)
line.imag = np.random.uniform(0, 1000, line_length)
times_basic.append(timeit.timeit(lambda: translate_basic(dataset1, offset), number=20))
times_threaded.append(
timeit.timeit(lambda: translate_threaded(dataset1, offset), number=20))
thread_pool.close()
thread_pool.terminate()
plt.plot(line_lengths, times_basic, '.-r')
plt.plot(line_lengths, times_threaded, '.-b')
plt.show()
Pivot point is ~3.5k points per lines.