Usar o GNU Parallel é, de longe, a maneira mais fácil de paralelizar tarefas em Python (ou outros jobs). Os resultados dos meus testes mostram (como deveria) que ele tem a perfomance muito similar à spawnar os processos direto do Python:
clacerda@air:~/temp$ python3 kht_test.py (alterado para roda 1 vez apenas) n = 30
----------------
Testando com 400 threads:
threadpool 0.006713270995533094
t_executor 0.013106929000059608
thread 0.033935421000933275
pool 0.04435754000587622
p_executor 0.10225035699841101
process 0.5674241800006712
clacerda@air:~/temp$ time seq 1 400 | parallel python3 fib.py
real 0m0,484s
Mas a grande beleza do parallel é ser incrivelmente simples, você não precisa se preocupar com sincronização, bloqueios ou pontos de encontro.
A função é simplesmente:
fib.py
def fibonacci(n = 30):
a, b = 0, 1
for i in range(n):
a, b = b, a+b
return a
fibonacci()
Usando o número certo de processos, você pode acelerar sua aplicação ao máximo potencial dos núcleos do seu CPU. Embora talvez não atinja a velocidade de um pool de bem ajustado, é o melhor "custo benefico" que você pode ter em Python para acelerar scripts. Se o desempenho for crítico, use uma linguagem compilada em primeiro lugar, mas para uma aceleração rápida e eficaz de scripts, o GNU Parallel é o rei!
Vamos simular um processo intensivo de CPU que queremos tornar mais rápido utilizando todos os núcleos do meu CPU. Neste caso, o parallel é perfeito:
Repetindo o teste com n = 1000000 e 4 threads.
`----------------
Testando com 4 threads:
process 23.90339469400351
pool 24.15610667699366
p_executor 25.45334278300288
thread 44.84984873000212
threadpool 44.986978027001896
t_executor 47.90096559400263
clacerda@air:~/temp$ time seq 1 4 | parallel python3 fib.py
real 0m24,387s```