Yukarıdaki @TemporalBeing yanıtı için düzeltme, greenlets iş parçacıklarından daha hızlı değildir ve bir eşzamanlılık sorununu çözmek için 60000 iş parçacığı oluşturmak yanlış bir programlama tekniğidir , bunun yerine küçük bir iş parçacığı havuzu uygundur. İşte daha makul bir karşılaştırma ( bu SO yazı alıntı insanlar yanıt olarak benim reddit yazı).
import gevent
from gevent import socket as gsock
import socket as sock
import threading
from datetime import datetime
def timeit(fn, URLS):
t1 = datetime.now()
fn()
t2 = datetime.now()
print(
"%s / %d hostnames, %s seconds" % (
fn.__name__,
len(URLS),
(t2 - t1).total_seconds()
)
)
def run_gevent_without_a_timeout():
ip_numbers = []
def greenlet(domain_name):
ip_numbers.append(gsock.gethostbyname(domain_name))
jobs = [gevent.spawn(greenlet, domain_name) for domain_name in URLS]
gevent.joinall(jobs)
assert len(ip_numbers) == len(URLS)
def run_threads_correctly():
ip_numbers = []
def process():
while queue:
try:
domain_name = queue.pop()
except IndexError:
pass
else:
ip_numbers.append(sock.gethostbyname(domain_name))
threads = [threading.Thread(target=process) for i in range(50)]
queue = list(URLS)
for t in threads:
t.start()
for t in threads:
t.join()
assert len(ip_numbers) == len(URLS)
URLS_base = ['www.google.com', 'www.example.com', 'www.python.org',
'www.yahoo.com', 'www.ubc.ca', 'www.wikipedia.org']
for NUM in (5, 50, 500, 5000, 10000):
URLS = []
for _ in range(NUM):
for url in URLS_base:
URLS.append(url)
print("--------------------")
timeit(run_gevent_without_a_timeout, URLS)
timeit(run_threads_correctly, URLS)
İşte bazı sonuçlar:
--------------------
run_gevent_without_a_timeout / 30 hostnames, 0.044888 seconds
run_threads_correctly / 30 hostnames, 0.019389 seconds
--------------------
run_gevent_without_a_timeout / 300 hostnames, 0.186045 seconds
run_threads_correctly / 300 hostnames, 0.153808 seconds
--------------------
run_gevent_without_a_timeout / 3000 hostnames, 1.834089 seconds
run_threads_correctly / 3000 hostnames, 1.569523 seconds
--------------------
run_gevent_without_a_timeout / 30000 hostnames, 19.030259 seconds
run_threads_correctly / 30000 hostnames, 15.163603 seconds
--------------------
run_gevent_without_a_timeout / 60000 hostnames, 35.770358 seconds
run_threads_correctly / 60000 hostnames, 29.864083 seconds
herkesin Python ile bloke olmama IO'su hakkındaki yanlış anlaşılma, Python yorumlayıcısının ağ bağlantılarının kendilerinden IO döndüğünden daha hızlı bir şekilde yuvalardan sonuç alma çalışmalarına katılabileceği inancıdır. Bu bazı durumlarda kesinlikle doğru olsa da, insanların düşündüğü kadar doğru değildir, çünkü Python yorumlayıcısı gerçekten, gerçekten yavaştır. Benim içinde buraya blog post , sana gevrek ve veritabanları veya DNS sunucularının gibi şeyler hızlı ağ erişimi ile ilgileniyor eğer, hatta çok basit şeyler için olduğunu göstermektedir bazı grafiksel profillerini göstermektedir, bu hizmetleri daha hızlı Python kodu daha çok geri gelebilir bu bağlantıların binlerceine katılabilir.