Dans Ruby, comment générer une longue chaîne de texte répété?

138

Quelle est la meilleure façon de générer rapidement une longue chaîne en rubis? Cela fonctionne, mais est très lent:

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

J'ai également remarqué que créer une chaîne d'une longueur décente, puis l'ajouter à une chaîne existante jusqu'à la longueur souhaitée fonctionne beaucoup plus rapidement:

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

D'autres suggestions?

Markus Orrelly
la source
1
Le meilleur moyen serait d'utiliser JRuby et d'utiliser StringBuffer. Oooooh.
Jonathan Feinberg

Réponses:

307
str = "0" * 999999
FMc
la source
22
En effet, très étrange, regardez à quel point Python est différent et élégant str = "0" * 999999
:;
1
Pourquoi la commande est-elle importante avec Ruby? Quand je 99999 * "0"reçoisTypeError: String can't be coerced into Fixnum
Steven
16
@Steven Du point de vue de Ruby, "0" * 999999est traité comme "0".*(999999)où se *trouve une méthode dans la Stringclasse. Cette méthode accepte les nombres comme arguments valides pour effectuer la réplication de chaînes. Lorsque vous inversez l'expression, nous obtenons 999999.*("0"). Maintenant, nous parlons de la *méthode dans la FixNumclasse, et cette méthode refuse de prendre des chaînes comme arguments. Cela pourrait certainement (par exemple, faire automatiquement de son mieux pour convertir l'argument en un FixNum) mais les concepteurs de langage ont décidé de ne pas adopter trop complètement les inspirations de Ruby's Perlish.
FMc
11

Une autre option relativement rapide est

str = '%0999999d' % 0

Bien que l'analyse comparative

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

Montre que la multiplication est encore plus rapide

               user     system      total        real
format  :  0.300000   0.080000   0.380000 (  0.405345)
multiply:  0.080000   0.080000   0.160000 (  0.172504)
rampion
la source
J'aime cette réponse, mais je n'arrive pas à la faire fonctionner pour autre chose que «0». Que dois-je faire si je veux 100 r?
yourdeveloperfriend
2
Cela ne fonctionnera pas avec d'autres symboles car il tire parti du remplissage numérique dans les chaînes de format. Les nombres peuvent être complétés avec des 0 devant ou derrière (pour les décimales) sans changer la valeur, les r ne fonctionnent pas comme ça.
Andrew