Savez-vous si l'utilisation de guillemets doubles au lieu de guillemets simples dans ruby diminue les performances de manière significative dans ruby 1.8 et 1.9.
donc si je tape
question = 'my question'
est-ce plus rapide que
question = "my question"
J'imagine que ruby essaie de déterminer si quelque chose doit être évalué lorsqu'il rencontre des guillemets doubles et passe probablement quelques cycles à le faire.
ruby
performance
syntax
dimus
la source
la source
Réponses:
Remarque: j'ai mis à jour cela pour le faire fonctionner avec les versions plus récentes de Ruby, j'ai nettoyé l'en-tête et exécuté le benchmark sur un système plus rapide.
Cette réponse omet certains points clés. Voir en particulier ces autres réponses concernant l' interpolation et la raison pour laquelle il n'y a pas de différence significative de performances lors de l'utilisation de guillemets simples ou doubles.
la source
'
et"
car ils sont analysés à la même chose.Résumé: pas de différence de vitesse; ce grand guide de style collaboratif Ruby recommande d'être cohérent. J'utilise maintenant
'string'
sauf si une interpolation est nécessaire (option A dans le guide) et je l'aime, mais vous verrez généralement plus de code avec"string"
.Détails:
Théoriquement, cela peut faire une différence lorsque votre code est analysé , mais non seulement si vous ne vous souciez pas du temps d'analyse en général (négligeable par rapport au temps d'exécution), vous ne pourrez pas trouver de différence significative dans ce cas.
L'important est que quand il sera exécuté, ce sera exactement la même chose .
L'analyse comparative montre seulement un manque de compréhension du fonctionnement de Ruby. Dans les deux cas, les chaînes seront analysées en a
tSTRING_CONTENT
(voir la source dansparse.y
). En d'autres termes, le CPU effectuera exactement les mêmes opérations lors de la création'string'
ou"string"
. Les mêmes bits seront inversés exactement de la même manière. L'analyse comparative ne montrera que les différences qui ne sont pas significatives et dues à d'autres facteurs (démarrage du GC, etc.); rappelez-vous, il ne peut y avoir aucune différence dans ce cas! Les micro-benchmarks comme ceux-ci sont difficiles à obtenir. Voir mon bijoufruity
pour un outil décent pour cela.Notez que s'il y a interpolation de la forme
"...#{...}..."
, celle-ci est analysée en atSTRING_DBEG
, un groupe detSTRING_DVAR
pour chaque expression dans#{...}
et une finaletSTRING_DEND
. Ce n'est que s'il y a interpolation, ce qui n'est pas le but de l'OP.J'avais l'habitude de vous suggérer d'utiliser des guillemets doubles partout (il est plus facile de l'ajouter
#{some_var}
plus tard), mais j'utilise maintenant des guillemets simples sauf si j'ai besoin d'une interpolation\n
, etc ... Je l'aime visuellement et c'est un peu plus explicite, car besoin d'analyser la chaîne pour voir si elle contient une expression.la source
#{n}
qu'il ferait une conversion de nombre). Ne montre-t-il pas les différences d'analyse ?.Personne n'a cependant mesuré la concaténation par rapport à l'interpolation:
Plus précisément, note
assign interp = 2.62
vsconcat single = 3.76
. Cerise sur le gâteau, je trouve aussi l'interpolation plus lisible que'a' + var + 'b'
surtout en ce qui concerne les espaces.la source
Aucune différence - sauf si vous utilisez l'
#{some_var}
interpolation de chaîne de style. Mais vous n'obtenez des performances que si vous le faites réellement.Modifié à partir de l' exemple de Zetetic :
production
la source
Les guillemets simples peuvent être très légèrement plus rapides que les guillemets doubles car le lexer n'a pas à vérifier les
#{}
marqueurs d'interpolation. Selon l'implémentation, etc. Notez qu'il s'agit d'un coût d'analyse et non d'un coût d'exécution.Cela dit, la vraie question était de savoir si l'utilisation de chaînes entre guillemets "diminue les performances d'une manière significative", à laquelle la réponse est un "non" décisif. La différence de performance est si incroyablement petite qu'elle est complètement insignifiante par rapport à tout problème de performance réel. Ne perds pas ton temps.
L'interpolation réelle est une autre histoire, bien sûr.
'foo'
sera presque exactement 1 seconde plus rapide que"#{sleep 1; nil}foo"
.la source
Les guillemets doubles nécessitent deux fois plus de frappes que les guillemets simples. Je suis toujours pressé. J'utilise des guillemets simples. :) Et oui, je considère que c'est un "gain de performance". :)
la source
Je pensais que j'ajouterais une comparaison de 1.8.7 et 1.9.2. Je les ai courus plusieurs fois. La variance était d'environ + -0,01.
ruby 1.8.7 (niveau de correctif 302 du 16/08/2010) [x86_64-linux]
ruby 1.9.2p0 (révision 29036 du 18/08/2010) [x86_64-linux]
la source
Il n'y a pas de différence significative dans les deux sens. Il faudrait que ce soit énorme pour que cela compte.
À l'exception des moments où vous êtes sûr qu'il y a un problème réel avec le timing, optimisez la maintenabilité du programmeur.
Les coûts du temps machine sont très très faibles. Le coût du temps du programmeur pour écrire du code et le maintenir est énorme.
À quoi sert une optimisation pour gagner des secondes, voire des minutes d'exécution sur des milliers d'exécutions si cela signifie que le code est plus difficile à maintenir?
Choisissez avec un style et respectez-le, mais ne choisissez pas ce style en fonction de millisecondes d'exécution statistiquement insignifiantes.
la source
Je pensais moi aussi que les chaînes entre guillemets pourraient être plus rapides à analyser pour Ruby. Cela ne semble pas être le cas.
Quoi qu'il en soit, je pense que le point de repère ci-dessus mesure la mauvaise chose, cependant. Il va de soi que l'une ou l'autre des versions sera analysée dans les mêmes représentations de chaînes internes afin d'obtenir la réponse quant à la plus rapide à analyser, nous ne devrions pas mesurer les performances avec des variables de chaîne, mais plutôt la vitesse d'analyse des chaînes de Ruby.
Les courses répétées ne semblent pas faire beaucoup de différence. Il faut toujours à peu près le même temps pour analyser l'une ou l'autre version de la chaîne.
la source
C'est certainement possible en fonction de l'implémentation, mais la partie numérisation de l'interpréteur ne doit regarder chaque caractère qu'une seule fois. Il aura juste besoin d'un état supplémentaire (ou d'un ensemble d'états possible) et de transitions pour gérer les blocs # {}.
Dans un scanner basé sur une table, il ne s'agira qu'une seule recherche pour déterminer la transition, et se produira de toute façon pour chaque personnage.
Lorsque l'analyseur obtient la sortie du scanner, on sait déjà qu'il devra évaluer le code dans le bloc. Ainsi, la surcharge n'est en réalité que la surcharge de mémoire dans le scanner / analyseur pour gérer le bloc # {}, que vous payez dans les deux cas.
À moins que je manque quelque chose (ou que je me souvienne mal des détails de construction du compilateur), ce qui est également certainement possible :)
la source
la source
Il y en a un que vous avez tous manqué.
ICI doc
essaye ça
Cela m'a donné
et
donc c'est certainement mieux que concat et écrire tous ces put.
J'aimerais voir Ruby enseigné davantage dans le sens d'un langage de manipulation de documents.
Après tout, ne faisons-nous pas vraiment cela dans Rails, Sinatra et en exécutant des tests?
la source
J'ai modifié la réponse de Tim Snowhite.
Résultats:
la source
J'ai essayé ce qui suit:
Et ce sont les sorties:
1.
2.
3.
4.
5.
6.
7.
8.
9.
dix.
Si je ne me suis pas trompé, il me semble que les deux prennent à peu près le même temps, même si les guillemets simples sont légèrement plus rapides dans la plupart des cas.
la source