Отличие заключается в том, что из-<<
работ на месте он несколько быстрее, чем +=
. Следующий код
require 'benchmark'
a = ''
b= ''
puts Benchmark.measure {
100000.times { a << 'test' }
}
puts Benchmark.measure {
100000.times { b += 'test' }
}
дает
0.000000 0.000000 0.000000 ( 0.004653)
0.060000 0.060000 0.120000 ( 0.108534)
Update
я изначально неправильно понял вопрос. Вот что происходит. Переменные Ruby хранят только ссылки на объекты, а не сами объекты. Вот упрощенный код, который делает то же, что и у вас, и имеет ту же проблему. Я сказал ему напечатать temp
и words_array
на каждой итерации петель.
def helper(word)
words_array = []
word.length.times do |i|
temp = ''
(i...word.length).each do |j|
temp << word[j]
puts "temp:\t#{temp}"
words_array << temp unless words_array.include?(temp)
puts "words:\t#{words_array}"
end
end
words_array
end
p helper("cat")
Вот что она печатает:
temp: c
words: ["c"]
temp: ca
words: ["ca"]
temp: cat
words: ["cat"]
temp: a
words: ["cat", "a"]
temp: at
words: ["cat", "at"]
temp: t
words: ["cat", "at", "t"]
["cat", "at", "t"]
Как вы можете видеть, во время каждой итерации внутреннего цикла после первого, рубин, просто заменив последний элемент из words_array
. Это связано с тем, что words_array
содержит ссылку на строковый объект, на который ссылаются temp
, а <<
модифицирует этот объект вместо того, чтобы создавать новый объект.
На каждой итерации внешнего контура temp
установлен новый объект, и этот новый объект добавляется к words_array
, поэтому он не заменяет предыдущие элементы.
Конструкция +=
возвращает новый объект temp
на каждой итерации внутреннего цикла, поэтому он ведет себя так, как ожидалось.
Вы не сравниваете то же самое здесь? –
Спасибо @ sagarpandya82. Я починил это. – lwassink
Я согласен, что использование метода лопаты происходит быстрее, но мне было интересно в моем конкретном случае, почему лопата против + = отличается, потому что логика для меня имеет смысл – DanielSD