यह उम्मीद है।
आप इस बेंचमार्क को वीएम पर चलाते हैं, जिस पर सिस्टम कॉल की लागत भौतिक हार्डवेयर से अधिक है। जब गीवेंट सक्रिय होता है, तो यह अधिक सिस्टम कॉल उत्पन्न करता है (एपोल डिवाइस को संभालने के लिए), ताकि आप कम प्रदर्शन के साथ समाप्त हो जाएं।
आप स्क्रिप्ट पर स्ट्रेस का उपयोग करके आसानी से इस बिंदु की जांच कर सकते हैं।
gevent के बिना, भीतरी पाश उत्पन्न करता है:
recvfrom(3, ":931\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
recvfrom(3, ":941\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
gevent साथ
, आप की आवृत्तियां होगा:
recvfrom(3, ":221\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
recvfrom(3, 0x7b0f04, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(5, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=3, u64=3}}) = 0
epoll_wait(5, {{EPOLLIN, {u32=3, u64=3}}}, 32, 4294967295) = 1
clock_gettime(CLOCK_MONOTONIC, {2469, 779710323}) = 0
epoll_ctl(5, EPOLL_CTL_DEL, 3, {EPOLLIN, {u32=3, u64=3}}) = 0
recvfrom(3, ":231\r\n", 4096, 0, NULL, NULL) = 6
sendto(3, "*3\r\n$6\r\nINCRBY\r\n$10\r\ntestsocket\r"..., 41, 0, NULL, 0) = 41
जब recvfrom कॉल (EAGAIN) ब्लॉक कर रहा है, gevent वापस चला जाता है इवेंट लूप, फाइल डिस्क्रिप्टर इवेंट्स (epoll_wait) के इंतजार के लिए अतिरिक्त कॉल किए जाते हैं।
कृपया ध्यान दें कि इस तरह का बेंचमार्क किसी भी ईवेंट लूप सिस्टम के लिए सबसे खराब मामला है, क्योंकि आपके पास केवल एक फ़ाइल डिस्क्रिप्टर है, इसलिए कई डिस्क्रिप्टरों पर प्रतीक्षा संचालन को कारक नहीं बनाया जा सकता है। इसके अलावा, एसिंक I/Os यहां कुछ भी सुधार नहीं कर सकता क्योंकि सब कुछ तुल्यकालिक है।
यह भी Redis के लिए एक सबसे खराब स्थिति है क्योंकि:
यह सर्वर के लिए कई roundtrips उत्पन्न
इसे व्यवस्थित जोड़ता है/डिस्कनेक्ट (1000 बार), क्योंकि पूल UxDomainSocket समारोह में घोषित किया जाता है ।
वास्तव में अपने बेंचमार्क परीक्षण नहीं होता gevent, redis या redis-py: यह एक वी एम की क्षमता अभ्यास 2 प्रक्रियाओं के बीच एक पिंगपांग खेल बनाए रखने के लिए।
आप प्रदर्शन में वृद्धि करना चाहते हैं, तो आप की जरूरत है:
भर में लगातार बनाने उदाहरण के लिए, निम्न स्क्रिप्ट के साथ विचार करें:
#!/usr/bin/python
from gevent import monkey
monkey.patch_all()
import timeit
import redis
from redis.connection import UnixDomainSocketConnection
pool = redis.ConnectionPool(connection_class=UnixDomainSocketConnection, path = '/tmp/redis.sock')
def UxDomainSocket():
r = redis.Redis(connection_pool = pool)
p = r.pipeline(transaction=False)
p.set("testsocket", 1)
for i in range(100):
p.incr('testsocket', 10)
p.get('testsocket')
p.delete('testsocket')
p.execute()
print timeit.Timer(stmt='UxDomainSocket()', setup='from __main__ import UxDomainSocket').timeit(number=1000)
इस स्क्रिप्ट के साथ, मुझे लगभग 3x बेहतर प्रदर्शन मिलता है और लगभग गेवेंट के साथ कोई ओवरहेड नहीं मिलता है।
विस्तृत प्रतिक्रिया के लिए धन्यवाद। अगर मैं गहराई से मुद्दा समझता हूं जो मैंने किया है, वह केवल एक "ऑब्जेक्ट" है जिस पर इंतजार किया जा सकता है - उदाहरण के लिए मेरे पास रेडिस कनेक्शन का एक पूल था और मैं गीवेंट का उपयोग करता हूं तो यह मुझे बेहतर प्रदर्शन देगा (मानते हुए रेडिस रख सकते हैं)। बीटीडब्ल्यू वीएम (और यूएक्स सॉकेट) केवल परीक्षण के लिए था। उत्पादन अलग-अलग उदाहरण होंगे, – vivekv
यदि पाइपलाइन का उपयोग किया जाता है, तो "रेडिस लॉक" का उपयोग कैसे करें – Tallmad