রুবিতে স্ট্রিংয়ের পরিবর্তে প্রতীক কখন ব্যবহার করবেন?


99

যদি আমার স্ক্রিপ্টে একই স্ট্রিংয়ের কমপক্ষে দুটি উদাহরণ রয়েছে, তবে আমি কি পরিবর্তে একটি চিহ্ন ব্যবহার করব?

উত্তর:


176

টিএল; ডিআর

থাম্বের একটি সহজ নিয়ম হ'ল প্রতিবার অভ্যন্তরীণ শনাক্তকারীদের প্রয়োজন হলে প্রতীক ব্যবহার করা। রুবির জন্য <2.2 কেবলমাত্র যখন চিহ্নগুলি গতিশীলভাবে তৈরি করা হয় না তখন মেমরি ফুটো এড়ানোর জন্য ব্যবহার করুন।

পুরো উত্তর

গতিশীলভাবে উত্পাদিত শনাক্তকারীদের এগুলি ব্যবহার না করার একমাত্র কারণ হ'ল মেমোরি উদ্বেগ।

এই প্রশ্নটি খুব সাধারণ কারণ অনেক প্রোগ্রামিং ভাষায় চিহ্ন নেই, কেবল স্ট্রিং থাকে না এবং এইভাবে স্ট্রিংগুলি আপনার কোডে সনাক্তকারী হিসাবেও ব্যবহৃত হয়। চিহ্নগুলি কী বোঝাতে চাইছে তা নিয়ে আপনার চিন্তিত হওয়া উচিত , কেবল যখন আপনার প্রতীকগুলি ব্যবহার করা উচিত । প্রতীকগুলি সনাক্তকারী হতে বোঝায়। আপনি যদি এই দর্শন অনুসরণ করেন, সম্ভাবনা হ'ল আপনি জিনিসগুলি সঠিকভাবে করবেন।

চিহ্ন এবং স্ট্রিংগুলির প্রয়োগের মধ্যে বেশ কয়েকটি পার্থক্য রয়েছে। প্রতীকগুলি সম্পর্কে সর্বাধিক গুরুত্বপূর্ণ বিষয় হ'ল এগুলি অপরিবর্তনীয় । এর অর্থ তারা কখনই তাদের মান পরিবর্তন করতে পারে না। এর কারণে, চিহ্নগুলি স্ট্রিংয়ের চেয়ে দ্রুত ইনস্ট্যান্ট করা হয় এবং দুটি চিহ্নের তুলনা করার মতো কিছু ক্রিয়াকলাপও দ্রুত।

একটি প্রতীক অপরিবর্তনীয় এই বিষয়টি যে প্রতিবার আপনি প্রতীকটি উল্লেখ করে মেমরি সঞ্চয় করে তা রুবিকে একই জিনিস ব্যবহার করতে দেয়। সুতরাং প্রতিবার অনুবাদক যখনই এটি পড়েন :my_keyতখন এটি আবার ইনস্ট্যান্ট করার পরিবর্তে এটিকে স্মৃতি থেকে নিতে পারে। এটি প্রতিবার নতুন স্ট্রিং শুরু করার চেয়ে কম ব্যয়বহুল।

কমান্ড দিয়ে ইতিমধ্যে ইনস্ট্যান্ট করা সমস্ত প্রতীকের একটি তালিকা আপনি পেতে পারেন Symbol.all_symbols:

symbols_count = Symbol.all_symbols.count # all_symbols is an array with all 
                                         # instantiated symbols. 
a = :one
puts a.object_id
# prints 167778 

a = :two
puts a.object_id
# prints 167858

a = :one
puts a.object_id
# prints 167778 again - the same object_id from the first time!

puts Symbol.all_symbols.count - symbols_count
# prints 2, the two objects we created.

২.২ এর আগে রুবি সংস্করণগুলির জন্য, একবার কোনও প্রতীক ইনস্ট্যান্ট করা হলে, এই স্মৃতিটি আর কখনও ফ্রি হবে না । মেমরিটি মুক্ত করার একমাত্র উপায় হ'ল অ্যাপ্লিকেশনটি পুনরায় চালু করা। সুতরাং ভুলভাবে ব্যবহার করার সময় প্রতীকগুলি মেমরি ফুটো হওয়ার একটি প্রধান কারণ। মেমোরি ফুটো উত্পন্ন করার সহজ উপায়টি to_symব্যবহারকারী ইনপুট ডেটাতে পদ্ধতিটি ব্যবহার করা হয় , যেহেতু এই ডেটা সর্বদা পরিবর্তিত হবে, তাই মেমরির একটি নতুন অংশ চিরকালের জন্য সফ্টওয়্যার উদাহরণে ব্যবহৃত হবে। রুবি ২.২ প্রতীক আবর্জনা সংগ্রহকারী পরিচয় করিয়েছে , যা গতিশীলভাবে তৈরি হওয়া প্রতীকগুলি মুক্ত করে, তাই গতিশীলভাবে প্রতীকগুলি তৈরি করে স্মৃতি ফাঁস হওয়া এটি আর উদ্বেগের বিষয় নয়।

আপনার প্রশ্নের উত্তর:

আমার অ্যাপ্লিকেশন বা স্ক্রিপ্টে কমপক্ষে দুটি একই স্ট্রিং থাকলে আমি কি স্ট্রিংয়ের পরিবর্তে একটি চিহ্ন ব্যবহার করতে পারি?

আপনি যা সন্ধান করছেন তা যদি আপনার কোডটিতে অভ্যন্তরীণভাবে ব্যবহার করা হয় তবে এটি আপনাকে প্রতীক ব্যবহার করা উচিত। আপনি যদি আউটপুট মুদ্রণ করছেন তবে আপনার স্ট্রিংগুলি দিয়ে যাওয়া উচিত, এমনকি এটি একাধিকবার প্রদর্শিত হলেও এমনকি মেমরিতে দুটি পৃথক বস্তু বরাদ্দ করা উচিত।

এখানে যুক্তি দেওয়া হল:

  1. চিহ্নগুলি মুদ্রণ করা স্ট্রিংগুলি মুদ্রণের চেয়ে ধীর হবে কারণ সেগুলি স্ট্রিংয়ে ফেলেছে।
  2. প্রচুর আলাদা চিহ্ন থাকা আপনার অ্যাপ্লিকেশনটির সামগ্রিক মেমরির ব্যবহার বাড়িয়ে দেবে কারণ সেগুলি কখনই বিলোপযুক্ত হয় না। এবং আপনি একই সাথে আপনার কোড থেকে সমস্ত স্ট্রিং ব্যবহার করছেন না।

@ অ্যালানডার্ট দ্বারা কেসটি ব্যবহার করুন

@ অ্যালানডার্ট: আমি যদি এইচএমএল কোডে% ইনপুট {টাইপ:: চেকবক্স like এর মতো অনেকবার ব্যবহার করি তবে আমার চেকবক্স হিসাবে কী ব্যবহার করা উচিত?

হ্যা আমি.

@ অ্যালানডার্ট: তবে এইচটিএমএল পৃষ্ঠায় একটি চিহ্ন প্রিন্ট করার জন্য, এটি স্ট্রিংয়ে রূপান্তর করা উচিত, তাই না? এটা ব্যবহার করার পরে কি লাভ?

একটি ইনপুট ধরণ কি? আপনি যে ধরণের ইনপুটটি ব্যবহার করতে চান বা ব্যবহারকারীকে কী দেখাতে চান তার একটি সনাক্তকারী?

এটি সত্য যে এটি কোনও সময় এইচটিএমএল কোডে পরিণত হবে, তবে এই মুহুর্তে আপনি আপনার কোডের সেই লাইনটি লিখছেন, এটির অর্থ একটি সনাক্তকারী হতে হবে - এটি আপনাকে কী ধরণের ইনপুট ক্ষেত্রের প্রয়োজন তা সনাক্ত করে। সুতরাং এটি আপনার কোডে বারবার ব্যবহৃত হয় এবং সনাক্তকারী হিসাবে সর্বদা অক্ষরের একই "স্ট্রিং" থাকে এবং মেমরি ফাঁস উত্পন্ন করে না।

এটি বলেছিল, স্ট্রিংগুলি দ্রুত হয় কিনা তা আমরা কেন ডেটা মূল্যায়ন করব না?

এটি এর জন্য আমি তৈরি করা একটি সাধারণ মানদণ্ড:

require 'benchmark'
require 'haml'

str = Benchmark.measure do
  10_000.times do
    Haml::Engine.new('%input{type: "checkbox"}').render
  end
end.total

sym = Benchmark.measure do
  10_000.times do
    Haml::Engine.new('%input{type: :checkbox}').render
  end
end.total

puts "String: " + str.to_s
puts "Symbol: " + sym.to_s

তিনটি ফলাফল:

# first time
String: 5.14
Symbol: 5.07
#second
String: 5.29
Symbol: 5.050000000000001
#third
String: 4.7700000000000005
Symbol: 4.68

সুতরাং এসএমবোলগুলি ব্যবহার করা স্ট্রিং ব্যবহারের চেয়ে কিছুটা দ্রুত। তা কেন? এটি এইচএএমএল বাস্তবায়িত হয় তার উপর নির্ভর করে। আমার এইচএএমএল কোডটি দেখতে কিছুটা হ্যাক করতে হবে, তবে আপনি যদি সনাক্তকারী হিসাবে ধারণার মধ্যে চিহ্ন ব্যবহার করেন তবে আপনার আবেদনটি দ্রুত এবং নির্ভরযোগ্য হবে। যখন প্রশ্নগুলি ধর্মঘট হয়, তখন এটি বেঞ্চমার্ক করুন এবং আপনার উত্তরগুলি পান।


@ Andrewcockerham আপনার সরবরাহিত লিঙ্কটি কাজ করছে না (ত্রুটি -404) আপনাকে লিঙ্কটি থেকে শেষ /(পরে strings) সরিয়ে ফেলতে হবে । এটি এখানে: www.reactive.io/tips/2009/01/11/the-differences-between-ruby-… প্রতীক-ও-স্ট্রিং
অতুল খান্ডুরি

14

সহজ কথায় বলতে গেলে, একটি চিহ্ন একটি নাম, যা চরিত্রগুলি নিয়ে গঠিত, তবে স্থাবর হয় না। বিপরীতে, একটি স্ট্রিং হ'ল অক্ষরগুলির জন্য একটি অর্ডারযুক্ত ধারক, যার বিষয়বস্তু পরিবর্তন করার অনুমতি দেওয়া হয়।


4
+1 প্রতীক এবং স্ট্রিংগুলি সম্পূর্ণ আলাদা জিনিস। কোনটি ব্যবহার করা উচিত তা নিয়ে আসলেই কোনও বিভ্রান্তি নেই, যদি না তাদের খারাপভাবে শেখানো হয় (যেমন "প্রতীকটি কেবল একটি অপরিবর্তনীয় স্ট্রিং" ভ্রান্তি)।
জার্গ ডব্লু মিট্টাগ

@ জার্গডব্লিউমিত্যাগ: হুবহু
বরিস স্ট্যাটনিকি

4
আপনার একটি বক্তব্য আছে, তবে যে প্রশ্নটি করা হয়েছিল তার উত্তর দিবেন না। ওপি প্রতীকগুলির সাথে স্ট্রিংগুলিকে বিভ্রান্ত করছে, এটি বিভিন্ন জিনিস
বলাই

4
@ জার্গডব্লিউমিত্যাগ যা পুরো ওয়েব জুড়েই ঘটছে তা মনে হয়, আপনি ডকুমেন্টেশনটি না দেখলে বা এমন ভাগ্যবান না হন যে জিনিসগুলিকে সত্যই যেমন ব্যাখ্যা করার জন্য যত্নবান হন।
সরগস

5

কোডেডেমিতে আমি দেখতে পেয়েছি একটি সুন্দর স্ট্রিং বনাম প্রতীকগুলি বেনমার্ক:

require 'benchmark'

string_AZ = Hash[("a".."z").to_a.zip((1..26).to_a)]
symbol_AZ = Hash[(:a..:z).to_a.zip((1..26).to_a)]

string_time = Benchmark.realtime do
  1000_000.times { string_AZ["r"] }
end

symbol_time = Benchmark.realtime do
  1000_000.times { symbol_AZ[:r] }
end

puts "String time: #{string_time} seconds."
puts "Symbol time: #{symbol_time} seconds."

আউটপুটটি হ'ল:

String time: 0.21983 seconds.
Symbol time: 0.087873 seconds.

4
আসুন আমরা এটি একটি সেকেন্ডের দশম হ'ল এটিকে ভুলে যাব না।
কেসি

সবই আপেক্ষিক। কখনও কখনও শততম বিষয়।
ইউরি

4
এক মিলিয়ন পুনরাবৃত্তির চেয়ে এক সেকেন্ডের এক শততম? যদি এটি আপনার কাছে উপলব্ধ সেরা অপ্টিমাইজেশন ইতিমধ্যে আপনার প্রোগ্রামটি বেশ ভালভাবে অনুকূলিত হয় তবে আমার ধারণা।
কেসি

0
  • হ্যাশ কী সনাক্তকারী হিসাবে চিহ্ন ব্যবহার করুন

    {key: "value"}

  • প্রতীকগুলি আপনাকে একটি পৃথক ক্রমে পদ্ধতিতে কল করতে দেয়

     Def লিখুন (ফাইল :, তথ্য :, মোড: "ascii")
          # ব্রেভিটির জন্য সরানো হয়েছে
     শেষ
     লিখুন (তথ্য: 123, ফাইল: "test.txt")
  • স্ট্রিং হিসাবে রাখতে এবং স্মৃতি সংরক্ষণ করতে হিমশীতল করুন

    label = 'My Label'.freeze

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.