Temps nécessaire pour le code séquentiel (seq.py
),Pourquoi GIL n'autorise pas le code thread sous-performant?
import time
def countDown(n):
while n > 0:
n -= 1
n = 50000000
start = time.time()
countDown(n)
end = time.time()
print(end-start)
est,
$ python3.6 seq.py
4.209718227386475
$ python3.6 seq.py
4.007786750793457
$ python3.6 seq.py
4.0265843868255615
$
temps pris pour la version filetée (usingThreads.py
),
from threading import Thread
import time
def countDown(n):
while n > 0:
n -= 1
n = 50000000
t1 = Thread(target=countDown, args=(n//2,))
t1.daemon = True
t2 = Thread(target=countDown, args=(n//2,))
t2.daemon = True
start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print(end-start)
est
$ python3.6 usingThreads.py
4.1083903312683105
$ python3.6 usingThreads.py
4.093154668807983
$ python3.6 usingThreads.py
4.092989921569824
$ python3.6 usingThreads.py
4.116031885147095
$
$ nproc
4
$
interpréteur Python ne doit pas permettre à des fils liés CPU pour libérer GIL.
Attendons usingThreads.py
de prendre plus de temps d'exécution que seq.py
, parce que,
1) Tout un fil est en cours d'exécution à un moment, en dépit de 4 cœurs
2) Le temps pris pour tentatives infructueuses d'acquérir GIL de thread1 par thread2 (et vice versa) devrait ajouter un retard dans l'exécution.
Edit:
Avec n=500000000
$ python3.6 seq.py
40.22602105140686
$ python3.6 seq.py
40.510098457336426
$ python3.6 seq.py
40.04688620567322
$
$ python3.6 usingThreads.py
40.91394829750061
$ python3.6 usingThreads.py
42.30081081390381
$ python3.6 usingThreads.py
41.328694581985474
Question:
Pourquoi usingThread.py
une meilleure performance que seq.py
?
Il me semble que l'utilisation de threads est généralement plus lente, mais seulement plus rapide que l'une des seq.py fois. – barny
Je suppose que c'est à cause de votre utilisation de 'join()' dans la version filetée - qui supprime probablement la plupart des frais généraux généralement associés à l'utilisation des threads. – martineau
@martineau C'est la seule façon que je connaisse d'attendre que les threads soient terminés, puis de calculer le temps nécessaire pour terminer le travail. Comment éviter 'join()'? – overexchange