Wie generiere ich in Ruby eine lange Folge von wiederholtem Text?

138

Was ist der beste Weg, um schnell einen langen String in Rubin zu erzeugen? Das funktioniert, ist aber sehr langsam:

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

Mir ist auch aufgefallen, dass das Erstellen einer Zeichenfolge mit einer anständigen Länge und das anschließende Anhängen dieser Zeichenfolge an eine vorhandene Zeichenfolge bis zur gewünschten Länge viel schneller funktioniert:

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

Irgendwelche anderen Vorschläge?

Markus Orrelly
quelle
1
Der beste Weg wäre, JRuby und StringBuffer zu verwenden. Oooooh.
Jonathan Feinberg

Antworten:

307
str = "0" * 999999
FMc
quelle
22
In der Tat, sehr seltsam, schauen Sie, wie anders und elegant in Python aussieht : str = "0" * 999999;)
tokland
1
Warum ist die Reihenfolge bei Ruby wichtig? Wenn ich es 99999 * "0"bekomme, bekomme ichTypeError: String can't be coerced into Fixnum
Steven
16
@Steven Aus Rubys Sicht "0" * 999999wird behandelt, "0".*(999999)wo *sich eine Methode in der StringKlasse befindet. Diese Methode akzeptiert Zahlen als gültige Argumente, um eine Zeichenfolgenreplikation durchzuführen. Wenn Sie den Ausdruck umkehren, erhalten wir 999999.*("0"). Jetzt sprechen wir über die *Methode in der FixNumKlasse, und diese Methode weigert sich, Zeichenfolgen als Argumente zu verwenden. Es könnte sicherlich (zum Beispiel automatisch bemüht sein, das Argument in ein FixNum umzuwandeln), aber die Sprachdesigner entschieden sich dagegen, Rubys Perlish-Inspirationen zu vollständig zu akzeptieren.
FMc
11

Eine andere relativ schnelle Option ist

str = '%0999999d' % 0

Obwohl Benchmarking

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

Zeigt, dass die Multiplikation immer noch schneller ist

               user     system      total        real
format  :  0.300000   0.080000   0.380000 (  0.405345)
multiply:  0.080000   0.080000   0.160000 (  0.172504)
Rampion
quelle
Ich mag diese Antwort, aber ich kann sie anscheinend nicht für etwas anderes als '0' zum Laufen bringen. Was mache ich, wenn ich 100 Rs will?
Ihr Entwicklerfreund
2
Es funktioniert nicht mit anderen Symbolen, da das Auffüllen von Zahlen in Formatzeichenfolgen genutzt wird. Zahlen können mit Nullen vorne oder hinten (für Dezimalstellen) aufgefüllt werden, ohne den Wert zu ändern. Rs funktionieren so nicht.
Andrew