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

बेंचमार्किंग रूबी कोड

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

इस उदाहरण में, हमें हैश को स्ट्रिंग कुंजियों (जैसे {"foo" => "bar"} के साथ परिवर्तित करने का काम सौंपा गया है। प्रतीकों के साथ एक के लिए (जैसे {:foo => "bar"} ) पूरे उदाहरणों में, हम अंग्रेजी वर्णमाला के प्रत्येक अक्षर के लिए एक कुंजी और एक मान के साथ हैश का उपयोग करेंगे।

इस हैश को बिना टाइप किए जल्दी से जेनरेट करने के लिए, हम अक्षरों की एक श्रृंखला को अपने परीक्षण हैश में बदल देंगे। हम इसे input . में डालेंगे बाद में उपयोग करने के लिए चर।

input = ("a".."z").map {|letter| [letter, letter]}.to_h
# => {"a"=>"a", "b"=>"b", "c"=>"c", "d"=>"d", "e"=>"e", "f"=>"f", "g"=>"g", "h"=>"h", "i"=>"i", "j"=>"j", "k"=>"k", "l"=>"l", "m"=>"m", "n"=>"n", "o"=>"o", "p"=>"p", "q"=>"q", "r"=>"r", "s"=>"s", "t"=>"t", "u"=>"u", "v"=>"v", "w"=>"w", "x"=>"x", "y"=>"y", "z"=>"z"}

अब जबकि हमारे पास हमारा input है चर के साथ हमारे कार्यान्वयन का परीक्षण करने के लिए, हम यह देखने के लिए एक लिखेंगे कि यह कैसा प्रदर्शन करता है। हमारे इनपुट हैश में सभी कुंजियों को स्ट्रिंग्स के बजाय प्रतीकों में बदलने के लिए एक अच्छा वन-लाइनर इस तरह दिखता है:

input.map { |key, value| [key.to_sym, value] }.to_h
# => {:a=>"a", :b=>"b", :c=>"c", :d=>"d", :e=>"e", :f=>"f", :g=>"g", :h=>"h", :i=>"i", :j=>"j", :k=>"k", :l=>"l", :m=>"m", :n=>"n", :o=>"o", :p=>"p", :q=>"q", :r=>"r", :s=>"s", :t=>"t", :u=>"u", :v=>"v", :w=>"w", :x=>"x", :y=>"y", :z=>"z"}

यह कार्यान्वयन map . का उपयोग करता है प्रत्येक कुंजी-मूल्य जोड़ी के लिए एक ब्लॉक चलाने के लिए हैश पर लूप करने की विधि। ब्लॉक में, यह कुंजी को एक प्रतीक में परिवर्तित करता है और नई बनाई गई प्रतीक कुंजी और अछूते मान के साथ एक दो-तत्व सरणी देता है।

map . से परिणाम कमांड 26 कुंजी-मान सरणियों वाला एक सरणी है। चूँकि हमें हैश की आवश्यकता है, हम #to_h . का उपयोग करते हैं हमारे नए सरणी को वापस हैश में बदलने के लिए।

बेंचमार्क.माप

अब जबकि हमारे पास एक कार्यशील कार्यान्वयन है, हम रूबी के बेंचमार्क मॉड्यूल का उपयोग यह देखने के लिए कर सकते हैं कि यह कैसा प्रदर्शन करता है।

require 'benchmark'
 
input = ('a'..'z').map { |letter| [letter, letter] }.to_h
 
puts Benchmark.measure {
  50_000.times do
    input.map { |key, value| [key.to_sym, value] }.to_h
  end
}

Benchmark.measure एक ब्लॉक लेता है, जिसे निष्पादित करने में कितना समय लगता है, इसका ट्रैक रखते हुए निष्पादित किया जाता है। यह एक रिपोर्ट स्ट्रिंग देता है, जो puts . का उपयोग करके कंसोल पर प्रिंट होता है ।

चूंकि यह एक त्वरित कोड है, इसलिए यह सुनिश्चित करने के लिए कि हमें कुछ दृश्यमान परिणाम मिले, हम इसे 50,000 बार चलाते हैं।

$ ruby bench.rb
  0.810000   0.000000   0.810000 (  0.816964)

रिपोर्ट स्ट्रिंग चार नंबर दिखाती है, जो उपयोगकर्ता CPU समय . का प्रतिनिधित्व करते हैं (आपके कोड को निष्पादित करने में लगने वाला समय), सिस्टम CPU समय (कर्नेल में बिताया गया समय), उपयोगकर्ता और सिस्टम CPU समय दोनों को जोड़ा गया, और वास्तविक समय (या दीवार घड़ी का समय) जो ब्लॉक को ब्रैकेट में निष्पादित करने में लगा।

दीवार का समय हमें दिखाता है कि हम 800 मिलीसेकंड से थोड़ा अधिक समय में 50,000 से अधिक बार कोड के ब्लॉक को चला सकते हैं। जबकि यह एक प्रभावशाली संख्या है, हम इसका अर्थ तब तक नहीं जानते जब तक हम इसकी तुलना कोड के किसी अन्य कार्यान्वयन से नहीं करते।

बेंचमार्क.bm

इसके अलावा Benchmark.measure , रूबी Benchmark.bm प्रदान करता है , जो कई कोड नमूने चला सकता है और उनके परिणाम प्रिंट कर सकता है। प्रत्येक नमूने के लिए, हम Benchmark#report पर कॉल करेंगे एक नाम के साथ, और ब्लॉक निष्पादित किया जाना है।

require 'benchmark'
 
input = ("a".."z").map { |letter| [letter, letter] }.to_h
n = 50_000
 
Benchmark.bm do |benchmark|
  benchmark.report("Hash[]") do
    n.times do
      input.map { |key, value| [key.to_sym, value] }.to_h
    end
  end
 
  benchmark.report("{}.tap") do
    n.times do
      {}.tap do |new_hash|
        input.each do |key, value|
          new_hash[key.to_sym] = value
        end
      end
    end
  end
end

इस बेंचमार्क में, हम Benchmark.bm . का उपयोग करेंगे प्रत्येक 50,000 बार चलाकर दो कार्यान्वयन का परीक्षण करने के लिए। पहला माप खंड पहले के उदाहरण जैसा ही है।

दूसरे मापन ब्लॉक में, हम एक लंबे कार्यान्वयन का उपयोग करते हैं, जो सामने एक नया हैश बनाता है। यह स्ट्रिंग-कुंजी हैश पर लूप करता है, और प्रत्येक आइटम के लिए नए हैश में एक तत्व जोड़ता है। इस तरह, इसे हैश को एक सरणी में बदलने की जरूरत नहीं है, और समाप्त होने पर इसे वापस हैश में बदलना होगा।

बेंचमार्क को फिर से चलाना हमें दिखाएगा कि यह कार्यान्वयन 25% से अधिक तेज है, हालांकि कोड पहले की कोशिश की गई एक-लाइनर की तुलना में लंबा (और थोड़ा कम चालाक) है।

$ ruby bench.rb
       user     system      total        real
Hash[]  0.850000   0.000000   0.850000 (  0.851106)
{}.tap  0.610000   0.020000   0.630000 (  0.637070)

अधिक बेंचमार्किंग

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

टिप :बहुत से सामान्य मुहावरे पूर्व-बेंचमार्क हैं, और उनके परिणाम फास्ट-रूबी के रूप में प्रकाशित होते हैं। उदाहरणों को पढ़ने से आप भविष्य में कुछ बेंचमार्किंग बचा सकते हैं।

इस उदाहरण के लिए आप और अधिक विकल्पों का परीक्षण कर सकते हैं, और रूबी की बेंचमार्किंग लाइब्रेरी में बहुत अधिक परिष्कृत विशेषताएं हैं जिन्हें आप आज़मा सकते हैं, लेकिन यह एक अच्छा परिचय देता है कि रूबी में बेंचमार्किंग कैसे काम करती है। यदि आप बेंचमार्किंग के बारे में अधिक जानना चाहते हैं, या आपके कोई प्रश्न या सुझाव हैं, तो कृपया हमें @AppSignal पर बताएं।


  1. टेस्ट-कमिट-रिवर्ट:रूबी में लिगेसी कोड के परीक्षण के लिए एक उपयोगी कार्यप्रवाह

    ऐसा हम में से अधिकांश के साथ होता है। जैसे-जैसे सॉफ्टवेयर प्रोजेक्ट बढ़ते हैं, कोडबेस के कुछ हिस्से बिना व्यापक परीक्षण सूट के उत्पादन में समाप्त हो जाते हैं। जब आप कुछ महीनों के बाद कोड के उसी क्षेत्र पर फिर से नज़र डालते हैं, तो इसे समझना मुश्किल हो सकता है; इससे भी बदतर, एक बग हो सकता है, और हम न

  1. रूबी में 9 नई सुविधाएँ 2.6

    रूबी का एक नया संस्करण नई सुविधाओं और प्रदर्शन में सुधार के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज रूबी 2.5 और पुराने संस्करण पहले से ही अंतहीन श्रेणी के एक रूप का समर्थन करते हैं (Float::INFINITY के साथ) ), लेकिन रूबी 2.6 इसे अगले स्तर पर ले

  1. रूबी में स्थैतिक विश्लेषण

    मान लें कि आप अपने सभी तरीकों को खोजने के लिए अपने स्रोत कोड को पार्स करना चाहते हैं, जहां वे परिभाषित हैं और वे कौन से तर्क लेते हैं। आप यह कैसे कर सकते हैं? आपका पहला विचार इसके लिए एक रेगेक्सपी लिखना हो सकता है... लेकिन क्या कोई बेहतर तरीका है? हाँ! स्थिर विश्लेषण एक ऐसी तकनीक है जिसका उपय