Если в моем сценарии есть как минимум два экземпляра одной и той же строки, следует ли вместо этого использовать символ?
Простое практическое правило - использовать символы каждый раз, когда вам нужны внутренние идентификаторы. Для Ruby <2.2 используйте символы только тогда, когда они не генерируются динамически, чтобы избежать утечек памяти.
Единственная причина не использовать их для идентификаторов, которые генерируются динамически, - это проблемы с памятью.
Этот вопрос очень распространен, потому что многие языки программирования не имеют символов, только строки, и поэтому строки также используются в качестве идентификаторов в вашем коде. Вы должны беспокоиться о том, что символы призваны быть не только когда вы должны использовать символы . Символы предназначены для идентификаторов. Если вы будете следовать этой философии, скорее всего, вы все сделаете правильно.
Существует несколько различий между реализацией символов и строк. Самое главное в символах - это то, что они неизменны . Это означает, что их ценность никогда не изменится. Из-за этого символы создаются быстрее, чем строки, а некоторые операции, такие как сравнение двух символов, также выполняются быстрее.
Тот факт, что символ неизменяем, позволяет Ruby использовать один и тот же объект каждый раз, когда вы ссылаетесь на символ, экономя память. Таким образом, каждый раз, когда интерпретатор читает, :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.
Для версий Ruby до 2.2 после создания символа эта память больше никогда не будет освобождена . Единственный способ освободить память - перезапустить приложение. Таким образом, символы также являются основной причиной утечки памяти при неправильном использовании. Самый простой способ сгенерировать утечку памяти - использовать этот метод to_sym
для данных, вводимых пользователем, поскольку эти данные всегда будут меняться, и в экземпляре программного обеспечения навсегда будет использоваться новая часть памяти. Ruby 2.2 представил сборщик мусора символов , который освобождает символы, сгенерированные динамически, поэтому утечки памяти, возникающие при динамическом создании символов, больше не вызывают беспокойства.
Отвечая на ваш вопрос:
Верно ли, что я должен использовать символ вместо строки, если в моем приложении или скрипте есть как минимум две одинаковые строки?
Если вы ищете идентификатор, который будет использоваться внутри вашего кода, вам следует использовать символы. Если вы печатаете вывод, вы должны использовать строки, даже если они появляются более одного раза, даже выделяя два разных объекта в памяти.
Вот рассуждение:
@AlanDert: если я много раз использую что-то вроде% input {type:: checkbox} в коде haml, что мне следует использовать в качестве флажка?
Я да.
@AlanDert: Но чтобы распечатать символ на html-странице, его нужно преобразовать в строку, не так ли? в чем тогда смысл его использовать?
Какой тип входа? Идентификатор типа ввода, который вы хотите использовать, или что-то, что вы хотите показать пользователю?
Это правда, что в какой-то момент он станет HTML-кодом, но в тот момент, когда вы пишете эту строку своего кода, это значит быть идентификатором - он определяет, какое поле ввода вам нужно. Таким образом, он используется в вашем коде снова и снова, всегда имеет ту же «строку» символов, что и идентификатор, и не вызывает утечки памяти.
Тем не менее, почему бы нам не оценить данные, чтобы увидеть, быстрее ли строки?
Это простой тест, который я создал для этого:
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
Таким образом, использование smbols на самом деле немного быстрее, чем использование строк. Это почему? Это зависит от способа реализации HAML. Мне нужно было бы немного взломать код HAML, чтобы увидеть, но если вы продолжите использовать символы в концепции идентификатора, ваше приложение будет быстрее и надежнее. Когда возникают вопросы, сравните их и получите ответы.
/
(послеstrings
) из ссылки. Вот он: www.reactive.io/tips/2009/01/11/the-difference-between-ruby- символы-и-строкиПроще говоря, символ - это имя, состоящее из символов, но неизменное. Напротив, строка - это упорядоченный контейнер для символов, содержимое которых может изменяться.
источник
Вот отличный тест строк и символов, который я нашел на codecademy:
Результат:
источник
использовать символы в качестве идентификаторов хеш-ключей
{key: "value"}
символы позволяют вызывать метод в другом порядке
заморозить, чтобы сохранить как строку и сохранить память
label = 'My Label'.freeze
источник