Повторение строки N раз - умножение VS перечислителя - PullRequest
1 голос
/ 24 сентября 2019

В чем разница между использованием умножения (при условии, что n является целым числом):

new_string = string * n

и перечислителем:

new_string = ""
n.times do { new_string += string }`

Вывод выглядит одинаково, но я 'Я не уверен, какой метод правильный / правильный , чтобы сделать это.

Буду признателен за некоторую информацию по этому вопросу.

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Строка # * реализована в C, но я ожидаю, что Ruby-эквивалент будет следующим:

class String
  def *(n)
    return "" if n.zero?
    (n-1).times.reduce(dup) { |s,_| s << self }
  end
end

str = 'abc'
str*(3)
  #=> "abcabcabc"

Мы видим, что для n > 0, str добавляется к dup из str n-1 раз.Временные массивы не создаются.Это не изменяет str (str #=> "abc").

Теперь рассмотрим:

str = 'abc'
n = 3

new_string = ""
n.times do { new_string += str }  

Также это не мутирует str, но, поскольку new_string += str расширяется до

new_string = new_string + str

, мы видим, что правая сторона этоговыражение вызывает создание n массивов с переменной new_string, назначенной каждому по очереди.В результате, n-1 временных массивов становятся сиротами и должны собираться мусором.Это не проблема, но это относительно неэффективная операция.

0 голосов
/ 24 сентября 2019

Вывод должен отличаться.Первая опция создает новый экземпляр String, который содержит string, повторенные n раза.Второй параметр изменяет исходное значение string на каждой итерации, поэтому в результате он повторяется гораздо чаще, чем n раз.

Например:

string = 'Abc'
n = 3
n.times do { string += string }

значения string послепоследующие итерации будут:

init: Abc
'AbcAbc'
'AbcAbcAbcAbc'

Это может работать аналогичным образом, если вы используете другую строку в качестве буфера:

new_string = ""
n.times { new_string += string }

Я думаю, что string * n более эффективно использует память(только одно новое распределение).

...