Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

मेटाप्रोग्रामिंग की छिपी लागत

मेटाप्रोग्रामिंग एक बहुत ही फैंसी शब्द की तरह लगता है, लेकिन क्या यह अच्छा है?

यह उपयोगी हो सकता है, लेकिन बहुत से लोग यह नहीं समझते हैं कि मेटाप्रोग्रामिंग का उपयोग करने की कुछ लागतें हैं।

ठीक वैसे ही हम एक ही पृष्ठ पर हैं…

मेटाप्रोग्रामिंग क्या है बिल्कुल?

मैं मेटाप्रोग्रामिंग को किसी भी विधि का उपयोग करने के रूप में परिभाषित करता हूं:

  • आपके कोड की संरचना को बदल देता है (जैसे define_method )
  • एक स्ट्रिंग चलाता है जैसे कि यह आपके वास्तविक रूबी कोड का हिस्सा था (जैसे instance_eval )
  • किसी घटना की प्रतिक्रिया के रूप में कुछ करता है (जैसे method_missing )

तो मेटाप्रोग्रामिंग की लागत क्या है? मैं उन्हें 3 समूहों में वर्गीकृत करता हूं:

  • गति
  • पठनीयता
  • खोज योग्यता
<ब्लॉकक्वॉट>

नोट :आप यह भी कह सकते हैं कि एक चौथा समूह है:सुरक्षा . इसका कारण हैं eval तरीके, जो किसी भी प्रकार की सुरक्षा जांच नहीं करते हैं कि क्या पारित किया जा रहा है। आपको वह स्वयं करना होगा।

आइए उनमें से प्रत्येक के बारे में अधिक विस्तार से जानें!

गति

पहली लागत गति है क्योंकि अधिकांश मेटाप्रोग्रामिंग विधियां नियमित विधियों की तुलना में धीमी होती हैं।

यहां कुछ बेंचमार्किंग कोड दिए गए हैं:

require 'benchmark/ips'

class Thing
  def method_missing(name, *args)
  end

  def normal_method
  end

  define_method(:speak) {}
end

t = Thing.new

Benchmark.ips do |x|
  x.report("normal method")  { t.normal_method }
  x.report("missing method") { t.abc }
  x.report("defined method") { t.speak }

  x.compare!
end

परिणाम (रूबी 2.2.4) :

normal method:   7344529.4 i/s
defined method:  5766584.9 i/s - 1.34x  slower
missing method:  4777911.7 i/s - 1.54x  slower

जैसा कि आप दोनों मेटाप्रोग्रामिंग विधियों को देख सकते हैं (define_method &method_missing ) सामान्य विधि की तुलना में काफी धीमी हैं।

यहाँ कुछ दिलचस्प है जो मैंने खोजा…

ऊपर दिए गए परिणाम Ruby 2.2.4 . से हैं , लेकिन अगर आप इन बेंचमार्क को Ruby 2.3 . पर चलाते हैं या Ruby 2.4 ऐसा लगता है कि ये तरीके धीमे होते जा रहे हैं!

रूबी 2.4 बेंचमार्क परिणाम :

normal method:   8252851.6 i/s
defined method:  6153202.9 i/s - 1.39x  slower
missing method:  4557376.3 i/s - 1.87x  slower

मैंने इस बेंचमार्क को कई बार यह सुनिश्चित करने के लिए चलाया कि यह एक अस्थायी नहीं था।

लेकिन अगर आप ध्यान दें और प्रति सेकंड पुनरावृत्तियों को देखें (i/s ) ऐसा लगता है कि रूबी 2.3 के बाद से नियमित तरीके तेज हो गए हैं। यही कारण है method_missing बहुत धीमा दिखता है 🙂

पठनीयता

instance_eval . का उपयोग करते समय त्रुटि संदेश मददगार से कम हो सकते हैं / class_eval तरीके।

निम्नलिखित कोड पर एक नज़र डालें:

class Thing
  class_eval("def self.foo; raise 'something went wrong'; end")
end

Thing.foo

इसके परिणामस्वरूप निम्न त्रुटि होगी:

(eval):1:in 'foo': 'something went wrong...' (RuntimeError)

ध्यान दें कि हमें फ़ाइल का नाम याद आ रहा है (यह eval . कहता है इसके बजाय) और सही लाइन नंबर। अच्छी खबर यह है कि इसके लिए एक समाधान है, ये eval विधियाँ दो अतिरिक्त पैरामीटर लेती हैं:

  • एक फ़ाइल का नाम
  • एक पंक्ति संख्या

अंतर्निहित स्थिरांक का उपयोग करना __FILE__ और __LINE__ class_eval . के लिए पैरामीटर के रूप में आपको त्रुटि संदेश में सही जानकारी मिलेगी।

उदाहरण :

class Thing
  class_eval(
    "def foo; raise 'something went right'; end",
    __FILE__,
    __LINE__
  )
end

यह डिफ़ॉल्ट क्यों नहीं है?

मुझे नहीं पता, लेकिन अगर आप इन तरीकों का उपयोग करने जा रहे हैं तो यह ध्यान में रखना चाहिए 🙂

खोज योग्यता

मेटाप्रोग्रामिंग विधियां आपके कोड को कम खोजने योग्य, कम पहुंच योग्य (खराब दस्तावेज़ीकरण के माध्यम से) और डीबग करने में कठिन बनाती हैं।

यदि आप एक विधि परिभाषा की तलाश कर रहे हैं तो आप मेटाप्रोग्रामिंग के माध्यम से परिभाषित एक विधि को खोजने के लिए CTRL+F (या जो भी शॉर्टकट आप उपयोग करते हैं) करने में सक्षम नहीं होंगे, खासकर यदि विधि का नाम रन-टाइम पर बनाया गया हो।

निम्न उदाहरण 3 विधियों को परिभाषित करता है मेटाप्रोग्रामिंग का उपयोग करना:

class RubyBlog
  def create_post_tags
    types = ['computer_science', 'tools', 'advanced_ruby']

    types.each do |type|
      define_singleton_method(type + "_tag") { puts "This post is about #{type}" }
    end
  end
end

rb = RubyBlog.new

rb.create_post_tags
rb.computer_science_tag

उपकरण जो दस्तावेज़ीकरण उत्पन्न करते हैं (जैसे Yard या RDoc ) इन विधियों को नहीं ढूंढ सकता और उन्हें सूचीबद्ध नहीं कर सकता।

ये उपकरण कक्षाओं और विधियों को खोजने के लिए "स्टेटिक एनालिसिस" नामक तकनीक का उपयोग करते हैं। यह तकनीक केवल उन विधियों को खोज सकती है जो सीधे परिभाषित हैं (def . का उपयोग करके) वाक्य रचना)।

yard doc चलाने का प्रयास करें अंतिम उदाहरण के साथ, आप देखेंगे कि पाया गया एकमात्र तरीका create_post_tags . है ।

ऐसा दिखता है :

मेटाप्रोग्रामिंग की छिपी लागत

Yard बताने का एक तरीका है @method . का उपयोग करके अतिरिक्त विधियों का दस्तावेजीकरण करने के लिए टैग, लेकिन यह हमेशा व्यावहारिक नहीं होता है।

उदाहरण :

class Thing
  # @method build_report
  define_method(:build_report)
end

इसके अलावा यदि आप grep . जैसे टूल का उपयोग करने जा रहे हैं , ack , या आपके संपादक को विधि परिभाषाओं की खोज करने के लिए, मेटाप्रोग्रामिंग विधियों को खोजना कठिन होगा नियमित तरीकों की तुलना में।

<ब्लॉकक्वॉट>

"मुझे नहीं लगता कि साइडकीक किसी मेटाप्रोग्रामिंग . का उपयोग करता है बिल्कुल भी क्योंकि मुझे लगता है कि यह 95% समय की तुलना में अधिक कोड को अस्पष्ट करता है।" - माइक परहम, साइडकीक के निर्माता

निष्कर्ष

मेटाप्रोग्रामिंग के बारे में सब कुछ बुरा नहीं है। यह आपके कोड को अधिक लचीला बनाने के लिए सही परिस्थितियों में उपयोगी हो सकता है।

बस अतिरिक्त लागतों से अवगत रहें ताकि आप बेहतर निर्णय ले सकें।

इस पोस्ट को शेयर करना न भूलें अगर आपको यह उपयोगी लगा 🙂


  1. जावास्क्रिप्ट में जनरेटर.थ्रो () विधि।

    जेनरेटर.थ्रो () मेथड का उपयोग यील्ड में एरर पास करने के लिए किया जाता है। एक त्रुटि फेंककर और गुणों और मूल्य के साथ लौटाने वाली वस्तु को फेंकने के बाद जनरेटर निष्पादन को फिर से शुरू करता है। जावास्क्रिप्ट में जनरेटर.थ्रो () के लिए कोड निम्नलिखित है - उदाहरण <!DOCTYPE html> <html lang="

  1. सर्वश्रेष्ठ असीमित मुफ्त वीपीएन सेवाएं (और उनकी छिपी लागत)

    वीपीएन का उपयोग करने के लाभ सर्वविदित हैं। यदि आपने अपने वर्कफ़्लो में एक को एकीकृत करने का निर्णय लिया है, तो आप एक निःशुल्क समाधान के साथ शुरुआत करने का प्रयास कर सकते हैं। चूंकि कई मुफ़्त ऑफ़र आपके द्वारा उनके माध्यम से भेजे जाने वाले डेटा की मात्रा को सीमित कर देते हैं, इसलिए एक मुफ्त असीमित वीप

  1. रूबी उपनाम कीवर्ड का उपयोग कैसे करें

    आप रूबी पद्धति को दो तरह से वैकल्पिक नाम दे सकते हैं: उपनाम (कीवर्ड) उपनाम_विधि क्योंकि वे एक ही काम को थोड़े अलग तरीके से करते हैं, यह एक भ्रमित करने वाला विषय हो सकता है। यह छवि मतभेदों का सारांश है : आइए एक ठोस समझ पाने के लिए इन अंतरों को और अधिक विस्तार से देखें! उपनाम कीवर्ड सबसे पहले