Jak w Rubim wygenerować długi ciąg powtarzającego się tekstu?

138

Jaki jest najlepszy sposób na szybkie wygenerowanie długiego ciągu w rubinie? To działa, ale działa bardzo wolno:

str = ""
length = 100000
(1..length).each {|i| str += "0"}

Zauważyłem również, że tworzenie łańcucha o przyzwoitej długości, a następnie dołączanie go do istniejącego ciągu do żądanej długości działa znacznie szybciej:

str = ""
incrementor = ""
length = 100000
(1..1000).each {|i| incrementor += "0"}
(1..100).each {|i| str += incrementor}

Jakieś inne sugestie?

Markus Orrelly
źródło
1
Najlepszym sposobem byłoby użycie JRuby i StringBuffer. Oooooh.
Jonathan Feinberg

Odpowiedzi:

307
str = "0" * 999999
FMc
źródło
22
Rzeczywiście, bardzo dziwnie, spójrz jak inaczej i elegancko wygląda w Pythonie str = "0" * 999999
:;
1
Dlaczego kolejność w Rubim jest ważna? Kiedy 99999 * "0"dostanęTypeError: String can't be coerced into Fixnum
Steven
16
@Steven Z punktu widzenia Rubiego "0" * 999999jest traktowany jako metoda "0".*(999999)gdzie *jest metodą w Stringklasie. Ta metoda akceptuje liczby jako prawidłowe argumenty do wykonywania replikacji ciągów. Kiedy odwrócisz wyrażenie, otrzymamy 999999.*("0"). Teraz mówimy o *metodzie w FixNumklasie, a ta metoda odmawia przyjęcia łańcuchów jako argumentów. Z pewnością mogłoby to (na przykład automatycznie dokładać wszelkich starań, aby przekształcić argument w FixNum), ale projektanci języka zdecydowali się nie wykorzystywać w pełni inspiracji Ruby Perlish.
FMc
11

Inną stosunkowo szybką opcją jest

str = '%0999999d' % 0

Chociaż testy porównawcze

require 'benchmark'
Benchmark.bm(9)  do |x|
  x.report('format  :') { '%099999999d' % 0 }
  x.report('multiply:') { '0' * 99999999 }
end

Pokazuje, że mnożenie jest nadal szybsze

               user     system      total        real
format  :  0.300000   0.080000   0.380000 (  0.405345)
multiply:  0.080000   0.080000   0.160000 (  0.172504)
rampion
źródło
Podoba mi się ta odpowiedź, ale nie mogę sprawić, by działała dla niczego innego niż „0”. Co mam zrobić, jeśli chcę 100 rs?
yourdeveloperfriend
2
Nie będzie działać z innymi symbolami, ponieważ wykorzystuje dopełnienie liczb w ciągach formatujących. Liczby mogą być dopełniane zerami z przodu lub z tyłu (dla ułamków dziesiętnych) bez zmiany wartości, r nie działają w ten sposób.
Andrew,