Символы Ruby не собираются мусором!? Тогда не лучше ли использовать String?

Если вы создаете 10000 строк в цикле, необходимо собрать много мусора, который использует много ресурсов.

Если вы делаете то же самое с символами, вы создаете объекты, которые не могут быть собраны с мусором.

Что хуже?

Ответ 1

Видя, как символы почти всегда создаются с помощью литералов, здесь не так много потенциала для взрыва памяти. Их поведение в значительной степени требуется их использованием: каждый раз, когда вы ссылаетесь на символ, он тот же.

Аналогично, строки должны быть уникальными в Ruby. Это связано с тем, как они используются - обработка текста и т.д.

Определите, какой из них использовать в зависимости от их семантики, преждевременно не оптимизируйте.

Ответ 2

Если вы ссылаетесь на один и тот же символ в своем цикле, то ему не нужно воссоздавать этот объект каждый раз, когда я .e.

while i < 10000
  i += 1
  :im_using_this_symbol_here
end

Теперь, если вместо этого вы используете строку, строка будет воссоздана 10K раз. В общем, используйте символы в тех случаях, когда вы почти рассматриваете литерал как константу или ключ. Очень хорошим примером для меня было бы

link_to "News", :action => 'news'

вместо

link_to "News", "action" => 'news'

действие снова и снова используется в вашем приложении.

Ответ 3

Если вы используете Ruby 2.2.0 или новее, обычно должно быть нормально динамически создавать множество символов, потому что они будут собирать мусор в соответствии с Объявление Ruby 2.2.0-preview1, в котором есть ссылка на подробнее о новом символе GC. Однако, если вы передаете свои динамические символы на какой-то код, который преобразует его в ID (внутренняя концепция реализации Ruby, используемая в исходном коде C), тогда в этом случае он будет закреплен и никогда не получит сбор мусора. Я не уверен, как обычно это происходит.

При принятии решения о том, следует ли использовать символы или строки, вы должны учитывать:

  • Символы не могут быть изменены после их создания.
  • Символы не имеют большого количества методов, которые имеют строки, например start_with?
  • Символы можно очень эффективно сравнить с eachother для равенства.
  • Символы должны представлять имя что-то в соответствии с Symbol docs. Я бы не использовал их для хранения всего, что нельзя было назвать именем.