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

फ्रीज और फ्रोजन का उपयोग कब करें? रूबी में

इन दिनों #freeze . देखना बहुत आम है रूबी कोड में उपयोग किया जाता है। लेकिन अक्सर यह पूरी तरह से स्पष्ट नहीं होता है कि फ्रीज का उपयोग क्यों किया जा रहा है। इस पोस्ट में हम सबसे सामान्य कारणों को देखेंगे जो एक डेवलपर चर को फ्रीज कर सकता है। प्रत्येक कारण को स्पष्ट करने के लिए, मैंने रेल कोडबेस और अन्य लोकप्रिय ओपन-सोर्स प्रोजेक्ट्स से उदाहरण कोड लिया है।

अपरिवर्तनीय स्थिरांक बनाना

रूबी में, स्थिरांक परिवर्तनशील होते हैं। यह थोड़ा भ्रमित करने वाला है, लेकिन कोड को समझना काफी आसान है। यहाँ, मैंने एक स्ट्रिंग स्थिरांक बनाया है और उसमें एक और स्ट्रिंग जोड़ रहा हूँ।

MY_CONSTANT = "foo"
MY_CONSTANT << "bar"
puts MY_CONSTANT.inspect # => "foobar"

#freeze का उपयोग करके, मैं एक स्थिरांक बनाने में सक्षम हूँ जो वास्तव में स्थिर है। इस बार, जब मैं स्ट्रिंग को संशोधित करने का प्रयास करता हूं, तो मुझे एक रनटाइम त्रुटि मिलती है।

MY_CONSTANT = "foo".freeze
MY_CONSTANT << "bar" # => RuntimeError: can't modify frozen string

एक्शनडिस्पैच कोडबेस में इसका वास्तविक दुनिया का उदाहरण यहां दिया गया है। रेल संवेदनशील डेटा को "[FILTERED]" टेक्स्ट से बदलकर लॉग में छिपा देता है। यह पाठ एक स्थिर स्थिरांक में संगृहीत है।

module ActionDispatch
  module Http
    class ParameterFilter
      FILTERED = '[FILTERED]'.freeze
      ...

ऑब्जेक्ट आवंटन कम करना

अपने रूबी ऐप को गति देने के लिए आप जो सबसे अच्छी चीजें कर सकते हैं, उनमें से एक है बनाई गई वस्तुओं की संख्या को कम करना। ऑब्जेक्ट आवंटन का एक कष्टप्रद स्रोत स्ट्रिंग अक्षर से आता है जो अधिकांश ऐप्स में छिड़का जाता है।

हर बार जब आप लॉग ("फोबार") जैसी विधि कॉल करते हैं, तो आप एक नया स्ट्रिंग ऑब्जेक्ट बनाते हैं। यदि आपका कोड प्रति सेकंड हजारों बार इस तरह की विधि को कॉल करता है, तो इसका मतलब है कि आप प्रति सेकंड हजारों तार बना रहे हैं (और कचरा इकट्ठा कर रहे हैं)। यह बहुत अधिक है!

सौभाग्य से, रूबी हमें एक रास्ता देती है। यदि हम स्ट्रिंग अक्षर को फ्रीज करते हैं, तो रूबी दुभाषिया केवल एक स्ट्रिंग ऑब्जेक्ट बनाएगा और भविष्य में उपयोग के लिए इसे कैश करेगा। मैंने जमे हुए बनाम गैर-जमे हुए स्ट्रिंग तर्कों के प्रदर्शन को दिखाते हुए एक त्वरित बेंचमार्क एक साथ रखा है। यह लगभग 50% प्रदर्शन वृद्धि दर्शाता है।

require 'benchmark/ips'

def noop(arg)
end

Benchmark.ips do |x|
  x.report("normal") { noop("foo") }
  x.report("frozen") { noop("foo".freeze)  }
end

# Results with MRI 2.2.2:
# Calculating -------------------------------------
#               normal   152.123k i/100ms
#               frozen   167.474k i/100ms
# -------------------------------------------------
#               normal      6.158M (± 3.3%) i/s -     30.881M
#               frozen      9.312M (± 3.5%) i/s -     46.558M

यदि आप रेल राउटर को देखते हैं तो आप इसे क्रिया में देख सकते हैं। चूंकि प्रत्येक वेब पेज अनुरोध के लिए राउटर का उपयोग किया जाता है, इसलिए इसे तेज़ होना चाहिए। इसका मतलब है कि बहुत सारे जमे हुए स्ट्रिंग अक्षर।

# excerpted from https://github.com/rails/rails/blob/f91439d848b305a9d8f83c10905e5012180ffa28/actionpack/lib/action_dispatch/journey/router/utils.rb#L15
def self.normalize_path(path)
  path = "/#{path}"
  path.squeeze!('/'.freeze)
  path.sub!(%r{/+\Z}, ''.freeze)
  path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
  path = '/' if path == ''.freeze
  path
end

रूबी में बिल्ट-इन ऑप्टिमाइज़ेशन>=2.2

रूबी 2.2 और बाद के संस्करण (एमआरआई) स्वचालित रूप से स्ट्रिंग अक्षर को फ्रीज कर देंगे जो हैश कुंजी के रूप में उपयोग किए जाते हैं।

user = {"name" => "george"}

# In Ruby >= 2.2
user["name"]

# ...is equivalent to this, in Ruby <= 2.1
user["name".freeze]

और Matz के अनुसार, रूबी 3 में सभी स्ट्रिंग अक्षर स्वचालित रूप से जमे हुए होंगे।

वैल्यू ऑब्जेक्ट और फंक्शनल प्रोग्रामिंग

जबकि रूबी एक कार्यात्मक प्रोग्रामिंग भाषा नहीं है, कई रूबीवादियों ने एक कार्यात्मक शैली में काम करने के मूल्य को देखना शुरू कर दिया है। इस शैली के मुख्य सिद्धांतों में से एक यह है कि आपको साइड इफेक्ट से बचना चाहिए। प्रारंभ होने के बाद वस्तुओं को कभी नहीं बदलना चाहिए।

कंस्ट्रक्टर के अंदर फ्रीज विधि को कॉल करके, यह गारंटी देना संभव है कि कोई वस्तु कभी नहीं बदलेगी। अनजाने में हुए किसी भी दुष्प्रभाव के परिणामस्वरूप एक अपवाद उठाया जाएगा।

class Point
  attr_accessor :x, :y
  def initialize(x, y)
    @x = x
    @y = y
    freeze
  end

  def change
    @x = 3
  end
end

point = Point.new(1,2)
point.change # RuntimeError: can't modify frozen Point

  1. एक मैट्रिक्स क्या है और रूबी में इसका उपयोग कैसे करें?

    मैट्रिक्स एक 2डी (2-आयामी) सरणी है जिसका उपयोग स्प्रेडशीट जैसे डेटा को स्टोर और काम करने के लिए किया जा सकता है। उनका उपयोग इसके लिए किया जा सकता है : टेबल गेम (शतरंज, चेकर्स, आदि) में बोर्ड का प्रतिनिधित्व करना सांख्यिकी और डेटा विश्लेषण प्लॉट और ग्राफ़ बनाना चूंकि यह एक शक्तिशाली डेटा संरचना ह

  1. रूबी में स्ट्रक्चर और ओपनस्ट्रक्चर का उपयोग कैसे करें?

    रूबी में स्ट्रक्चर क्या है? एक संरचना एक अंतर्निहित रूबी वर्ग है, इसका उपयोग नए वर्ग बनाने के लिए किया जाता है जो मूल्य वस्तुओं का उत्पादन करते हैं। संबंधित विशेषताओं को एक साथ संग्रहीत करने के लिए एक मूल्य वस्तु का उपयोग किया जाता है। यहां एक उदाहरण दिया गया है : एक Point दो निर्देशांकों के साथ

  1. रूबी स्ट्रिंग स्वरूपण

    आइए बात करते हैं कि आप रूबी में स्ट्रिंग्स को कैसे प्रारूपित कर सकते हैं। आप एक स्ट्रिंग को प्रारूपित क्यों करना चाहेंगे? ठीक है, हो सकता है कि आप ऐसे काम करना चाहें जैसे संख्या 10 से कम हो (उदाहरण:01, 02, 03…), या कुछ कंसोल आउटपुट कॉलम में अच्छी तरह से स्वरूपित हो। अन्य भाषाओं में आप printf . का