Questo è abbastanza interessante da analizzare. Ecco un codice per confrontare le prestazioni di greenlets rispetto multiprocessing piscina contro il multi-threading:
import gevent
from gevent import socket as gsock
import socket as sock
from multiprocessing import Pool
from threading import Thread
from datetime import datetime
class IpGetter(Thread):
def __init__(self, domain):
Thread.__init__(self)
self.domain = domain
def run(self):
self.ip = sock.gethostbyname(self.domain)
if __name__ == "__main__":
URLS = ['www.google.com', 'www.example.com', 'www.python.org', 'www.yahoo.com', 'www.ubc.ca', 'www.wikipedia.org']
t1 = datetime.now()
jobs = [gevent.spawn(gsock.gethostbyname, url) for url in URLS]
gevent.joinall(jobs, timeout=2)
t2 = datetime.now()
print "Using gevent it took: %s" % (t2-t1).total_seconds()
print "-----------"
t1 = datetime.now()
pool = Pool(len(URLS))
results = pool.map(sock.gethostbyname, URLS)
t2 = datetime.now()
pool.close()
print "Using multiprocessing it took: %s" % (t2-t1).total_seconds()
print "-----------"
t1 = datetime.now()
threads = []
for url in URLS:
t = IpGetter(url)
t.start()
threads.append(t)
for t in threads:
t.join()
t2 = datetime.now()
print "Using multi-threading it took: %s" % (t2-t1).total_seconds()
ecco i risultati:
Using gevent it took: 0.083758
-----------
Using multiprocessing it took: 0.023633
-----------
Using multi-threading it took: 0.008327
Credo che greenlet sostiene che non è vincolato da GIL a differenza la libreria multithreading. Inoltre, il dott. Greenlet dice che è pensato per le operazioni di rete. Per un'operazione intensiva di rete, il cambio di thread va bene e puoi vedere che l'approccio al multithreading è piuttosto veloce. Inoltre è sempre preferibile usare le librerie ufficiali di python; Ho provato a installare greenlet su Windows e ho riscontrato un problema di dipendenza da dll, quindi ho eseguito questo test su un Linux vm. Provare sempre a scrivere un codice con la speranza che funzioni su qualsiasi macchina.
@Imran Si tratta di greenthreads in Java. La mia domanda riguarda Greenlet in Python. Mi sto perdendo qualcosa ? – Rsh
Afaik, i thread in python non sono realmente concomitanti a causa del blocco dell'interprete globale. Quindi si ridurrebbe a confrontare il sovraccarico di entrambe le soluzioni. Anche se capisco che ci sono diverse implementazioni di Python, quindi questo potrebbe non valere per tutti loro. – didierc
@didierc CPython (e PyPy al momento) non interpreteranno il codice Python (byte) * in parallelo * (cioè, fisicamente fisicamente nello stesso momento su due core CPU distinti). Tuttavia, non tutto ciò che fa un programma Python è sotto GIL (esempi comuni sono syscalls incluse le funzioni I/O e C che rilasciano deliberatamente il GIL), e 'threading.Thread' è in realtà un thread del sistema operativo con tutte le ramificazioni. Quindi non è proprio così semplice. A proposito, Jython non ha GIL AFAIK e PyPy sta cercando di liberarsene. – delnan