रूबी के प्रदर्शन में बहुत सुधार हो रहा है, संस्करण दर संस्करण… और रूबी विकास टीम रूबी को और भी तेज बनाने के लिए हर संभव प्रयास कर रही है!
इन प्रयासों में से एक 3×3 परियोजना है।
लक्ष्य?
रूबी 3.0, रूबी 2.0 से 3 गुना तेज होगा ।
इस प्रोजेक्ट का एक हिस्सा नया MJIT कंपाइलर है, जो इस लेख का विषय है।
MJIT समझाया गया
MJIT का मतलब "विधि आधारित जस्ट-इन-टाइम कंपाइलर" है।
इसका क्या मतलब है?
रूबी आपके कोड को YARV निर्देशों में संकलित करती है , ये निर्देश रूबी वर्चुअल मशीन द्वारा चलाए जाते हैं।
JIT इसमें एक और परत जोड़ता है।
यह अक्सर उपयोग किए जाने वाले निर्देशों को संकलित करेगा बाइनरी कोड में।
परिणाम एक अनुकूलित बाइनरी है जो आपके कोड को तेज़ी से चलाता है।
यह कैसे काम करता है
आइए देखें कि एमजेआईटी इसे बेहतर ढंग से समझने के लिए कैसे काम करता है।
आप रूबी 2.6 और --jit
. के साथ JIT को सक्षम कर सकते हैं विकल्प।
इसे पसंद करें :
ruby --jit app.rb
रूबी 2.6 जेआईटी-विशिष्ट विकल्पों के एक सेट के साथ आता है जो हमें यह पता लगाने में मदद करेगा कि यह कैसे काम करता है। आप ruby --help
. चलाकर इन विकल्पों को देख सकते हैं ।
यहां विकल्पों की सूची दी गई है
- –जित-रुको
- –जित-वर्बोज़
- –जित-सेव-टेम्प्स
- –जित-मैक्स-कैश
- –जित-मिन-कॉल
यह क्रिया विकल्प एक अच्छा प्रारंभिक बिंदु लगता है!
हम --jit-wait
. का भी उपयोग करने जा रहे हैं , यह रूबी को तब तक प्रतीक्षा करता है जब तक कि इसे चलाने से पहले JIT कोड का संकलन नहीं हो जाता।
सामान्य ऑपरेशन के दौरान JIT एक वर्कर थ्रेड में कोड संकलित करता है और यह इसके खत्म होने का इंतजार नहीं करता है।
इसका परीक्षण करने के लिए आप यह कमांड चला सकते हैं:
ruby --disable-gems --jit --jit-verbose=1 --jit-wait -e "4.times { 123 }"
यह प्रिंट करता है :
Successful MJIT finish
खैर, यह बहुत दिलचस्प नहीं है, है ना?
JIT कुछ नहीं कर रहा है।
क्यों?
क्योंकि डिफ़ॉल्ट रूप से, JIT केवल तभी कार्य करता है जब किसी विधि को 5 बार कहा जाता है (jit-min-calls
) या अधिक।
अगर हम इसे चलाते हैं:
ruby --disable-gems --jit --jit-verbose=1 --jit-wait -e "5.times { 123 }"
अब हमें कुछ दिलचस्प मिलता है :
JIT success (32.1ms): block in <main>@-e:1 -> /tmp/_ruby_mjit_p13921u0.cमें ब्लॉक करें
यह क्या कहता है?
JIT ने एक ब्लॉक संकलित किया क्योंकि हमने इसे 5 बार कॉल किया, यह आपको बताता है:
- संकलन में कितना समय लगा (
32.1ms
), - बिल्कुल क्या संकलित किया गया था (
block in <main>
में ब्लॉक करें ) - जनरेट की गई फ़ाइल (
/tmp/_ruby_mjit_p13921u0.c
) इस संकलन के स्रोत के रूप में
यह फ़ाइल सी स्रोत कोड है जिसे एक ऑब्जेक्ट फ़ाइल (.o
. में संकलित किया गया है ) और फिर एक साझा लाइब्रेरी फ़ाइल में (.so
)।
यदि आप --jit-save-temps
. जोड़ते हैं तो आप इन फ़ाइलों तक पहुंच प्राप्त कर सकते हैं विकल्प।
यहां एक उदाहरण दिया गया है :
यह मेरी वर्तमान समझ है कि JIT कैसे काम करता है :
- विधि कॉलों की गणना करें
- जब एक विधि को 5 बार कॉल किया जाता है (
jit-min-calls
) जेआईटी को ट्रिगर करें - एसी फ़ाइल जिसमें इस पद्धति के निर्देश शामिल हैं, बनाई गई है (ये YARV निर्देश हैं, लेकिन इनलाइन हैं)
- पृष्ठभूमि में संकलन होता है (जब तक
--jit-wait
) जीसीसी जैसे नियमित सी कंपाइलर का उपयोग करना - जब संकलन किया जाता है तो परिणामी साझा लाइब्रेरी फ़ाइल का उपयोग तब किया जाता है जब इस विधि को कहा जाता है
आइए देखें कि यह कितना कारगर है।
MJIT का परीक्षण:क्या यह वास्तव में तेज़ है?
MJIT का लक्ष्य रूबी को तेज बनाना है।
अभी ऐसा करना कितना अच्छा है?
आइए जानें!
सबसे पहले, माइक्रोबेंचमार्क:
बेंचमार्क | परिणाम (JIT के बिना रूबी 2.6 की तुलना में) |
---|---|
जबकि | 8x तेज |
जबकि स्ट्रिंग एपेंड के साथ | 10% तेज |
गुणा के साथ (पूर्णांक) | 4x तेज |
गुणा के साथ (बिग्नम) | 20% धीमा |
स्ट्रिंग अपकेस | 10% तेज |
स्ट्रिंग मिलान | 2% धीमा |
स्ट्रिंग मैच? | 10% तेज |
10k यादृच्छिक संख्याओं के साथ सरणी | 20% तेज |
ऐसा लगता है कि प्रदर्शन हर जगह है, लेकिन कुछ ऐसा है जिसे हम इससे निकाल सकते हैं…
MJIT को वास्तव में लूप पसंद हैं!
लेकिन यह अधिक जटिल एप्लिकेशन के साथ कैसा व्यवहार करता है?
आइए एक साधारण सिनात्रा ऐप के साथ प्रयास करें :
require 'sinatra' get '/' do "apples, oranges & bananas" end
यह बहुत अधिक नहीं लग सकता है, लेकिन यह छोटा सा कोड 500 से अधिक विभिन्न तरीकों से चलता है। JIT को कुछ काम देने के लिए काफी है!
<ब्लॉकक्वॉट>विशिष्ट होने के लिए, यह सिनात्रा 2.0.4 पतली 1.7.2 के साथ है।
आप इस कमांड (अपाचे बेंच) के साथ बेंचमार्क चला सकते हैं:
ab -c 20 -t 10 https://localhost:4567/
ये परिणाम हैं :
आप इनसे बता सकते हैं कि रूबी 2.6 2.5 से तेज है, लेकिन JIT को सक्षम करने से सिनात्रा 11% धीमी हो जाती है !
क्यों?
मुझे नहीं पता, ऐसा इसलिए हो सकता है क्योंकि जेआईटी द्वारा ओवरहेड पेश किया गया है, या क्योंकि कोड अच्छी तरह से अनुकूलित नहीं है।
सी प्रोफाइलर (कॉलग्रिंड) के साथ मेरे परीक्षण से पता चलता है कि जेआईटी अनुकूलित कोड (संकलित सी फाइलें जिन्हें हमने पहले खोजा था) का उपयोग सिनात्रा के लिए बहुत कम है (2% से कम) ), लेकिन यह बहुत अधिक है (24.22% ) उस समय के विवरण के लिए जो 8x गति को बढ़ावा देता है।
JIT के साथ कुछ समय के बेंचमार्क के लिए परिणाम :
JIT के साथ सिनात्रा बेंचमार्क के परिणाम :
यह कारण का हिस्सा हो सकता है, मैं एक कंपाइलर विशेषज्ञ नहीं हूं इसलिए मैं इससे कोई निष्कर्ष नहीं निकाल सकता।
सारांश
MJIT एक "जस्ट-इन-टाइम कंपाइलर" है जो रूबी 2.6 में उपलब्ध है, इसे --jit
के साथ इनेबल किया जा सकता है। झंडा। MJIT आशाजनक है और कुछ छोटे कार्यक्रमों को गति दे सकता है, लेकिन अभी बहुत काम करना बाकी है!
अगर आपको यह लेख पसंद आया हो तो इसे अपने रूबी दोस्तों के साथ शेयर करना न भूलें 🙂
पढ़ने के लिए धन्यवाद।