Я работаю через Руби Коанс.
test_the_shovel_operator_modifies_the_original_string
Koan в about_strings.rb включает следующий комментарий:
При построении строк программисты на Ruby предпочитают оператор лопатки (<<) перед оператором плюс-равно (+ =). Зачем?
Я предполагаю, что это связано со скоростью, но я не понимаю действия под капотом, которые заставили бы оператора лопаты работать быстрее.
Кто-нибудь сможет объяснить подробности этого предпочтения?
ruby
string
optimization
Эрин Браун
источник
источник
Ответы:
Доказательство:
Так что
<<
изменяет исходную строку, а не создает новую. Причина этого заключается в том, что в rubya += b
используется синтаксическое сокращениеa = a + b
(то же самое относится и к другим<op>=
операторам), которое является присваиванием. С другой стороны,<<
псевдоним,concat()
который изменяет приемник на месте.источник
Array#join
это медленнее, чем использование<<
.Доказательство производительности:
источник
Друг, который изучает Ruby как его первый язык программирования, задал мне тот же вопрос, когда просматривал Strings in Ruby в серии Ruby Koans. Я объяснил это ему, используя следующую аналогию;
У вас есть стакан воды, который наполовину полон, и вам нужно пополнить свой стакан.
Первый способ сделать это - взять новый стакан, наполовину наполнив его водой из-под крана, а затем использовать этот второй наполовину полный стакан, чтобы наполнить свой стакан. Вы делаете это каждый раз, когда вам нужно пополнить свой стакан.
Второй способ - взять наполовину полный стакан и просто наполнить его водой прямо из-под крана.
В конце дня у вас будет больше очков для чистки, если вы решите выбрать новый стакан каждый раз, когда вам нужно пополнить свой стакан.
То же самое относится к оператору лопаты и оператору равенства плюс. Плюс оператор «равный» выбирает новый «стакан» каждый раз, когда ему необходимо пополнить свой стакан, в то время как оператор лопатки просто берет тот же стакан и наполняет его. В конце дня больше «стеклянной» коллекции для оператора Plus Plus.
источник
Это старый вопрос, но я просто наткнулся на него, и я не полностью удовлетворен существующими ответами. Есть много хороших моментов в том, что лопата << быстрее, чем конкатенация + =, но есть и семантическое соображение.
Принятый ответ от @noodl показывает, что << изменяет существующий объект на месте, тогда как + = создает новый объект. Поэтому вам нужно подумать, хотите ли вы, чтобы все ссылки на строку отражали новое значение, или вы хотите оставить существующие ссылки в покое и создать новое строковое значение для локального использования. Если вам нужны все ссылки, чтобы отразить обновленное значение, тогда вам нужно использовать <<. Если вы хотите оставить другие ссылки в покое, тогда вам нужно использовать + =.
Очень распространенным случаем является только одна ссылка на строку. В этом случае семантическая разница не имеет значения, и естественно предпочесть << из-за ее скорости.
источник
Поскольку он быстрее / не создает копию строки, <-> сборщик мусора запускать не нужно.
источник
malloc
/free
. Кроме того, некоторые более современные реализации Ruby, вероятно, полностью оптимизируют распределение объектов и конкатенацию строк. OTOH, мутирующие объекты ужасны для производительности GC.Хотя большинство ответов покрывают
+=
медленнее, потому что создает новую копию, важно иметь в виду, что+=
и<<
не взаимозаменяемы! Вы хотите использовать каждый в разных случаях.Использование
<<
также изменит любые переменные, на которые указываютb
. Здесь мы также мутируем,a
когда не хотим.Поскольку
+=
создает новую копию, она также оставляет все переменные, которые указывают на нее, без изменений.Понимание этого различия поможет вам избежать головной боли при работе с петлями!
источник
Хотя это и не прямой ответ на ваш вопрос, почему « Полностью перевернутая корзина» всегда была одной из моих любимых статей на Ruby. Он также содержит некоторую информацию о строках в отношении сборки мусора.
источник