কম্পিউটার

বেঞ্চমার্কিং রুবি কোড

আপনার কোডের পারফরম্যান্স পরিমাপ করতে সাহায্য করার জন্য রুবির স্ট্যান্ডার্ড লাইব্রেরিতে একটি বেঞ্চমার্কিং টুল রয়েছে। কোনটি দ্রুততম তা খুঁজে বের করার জন্য দুটি বাস্তবায়নের তুলনা করার সময় এটি সবচেয়ে কার্যকর।

এই উদাহরণে, আমাদেরকে স্ট্রিং কী দিয়ে হ্যাশ রূপান্তর করার দায়িত্ব দেওয়া হয়েছে (যেমন {"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 ব্যবহার করি আমাদের নতুন অ্যারেকে হ্যাশে রূপান্তর করতে।

Benchmark.measure

এখন যেহেতু আমাদের একটি কার্যকরী বাস্তবায়ন আছে, আমরা রুবির বেঞ্চমার্ক মডিউল ব্যবহার করে দেখতে পারি এটি কীভাবে কাজ করে৷

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 সময় (কার্নেলে কাটানো সময়), ব্যবহারকারী এবং সিস্টেম সিপিইউ সময় উভয়ই যোগ করা হয়েছে, এবং বন্ধনীতে ব্লক চালানোর জন্য প্রকৃত সময় (বা প্রাচীর ঘড়ির সময়)।

ওয়াল টাইম আমাদের দেখায় যে আমরা 50.000 বারের উপরে কোডের ব্লকটি 800 মিলিসেকেন্ডের কিছু বেশি সময়ে চালাতে পারি। যদিও এটি একটি চিত্তাকর্ষক সংখ্যা, আমরা কোডটির অন্য বাস্তবায়নের সাথে তুলনা না করলে এর অর্থ কী তা আমরা জানি না৷

Benchmark.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. RuboCop সহ রুবি কোড লিন্টিং এবং স্বয়ংক্রিয় ফর্ম্যাটিং

  2. টেস্ট-কমিট-রিভার্ট:রুবিতে লিগ্যাসি কোড পরীক্ষা করার জন্য একটি দরকারী কর্মপ্রবাহ

  3. রুবি 2.6-এ 9টি নতুন বৈশিষ্ট্য

  4. রুবি মধ্যে স্ট্যাটিক বিশ্লেষণ