Estoy trabajando a través de Ruby Koans.
El test_the_shovel_operator_modifies_the_original_string
Koan en about_strings.rb incluye el siguiente comentario:
Los programadores de Ruby tienden a favorecer al operador de la pala (<<) sobre el operador más igual a (+ =) al construir cadenas. ¿Por qué?
Supongo que implica velocidad, pero no entiendo la acción debajo del capó que haría que el operador de la pala sea más rápido.
¿Alguien podría explicar los detalles detrás de esta preferencia?
ruby
string
optimization
erinbrown
fuente
fuente
Respuestas:
Prueba:
Así que
<<
altera la cadena original en lugar de crear uno nuevo. La razón de esto es que en rubya += b
es una abreviatura sintáctica paraa = a + b
(lo mismo ocurre con los otros<op>=
operadores) que es una asignación. Por otro lado,<<
hay un aliasconcat()
que altera el receptor en el lugar.fuente
Array#join
es más lento que el uso<<
.Prueba de rendimiento:
fuente
Un amigo que está aprendiendo Ruby como su primer lenguaje de programación me hizo esta misma pregunta mientras revisaba Strings in Ruby en la serie Ruby Koans. Se lo expliqué usando la siguiente analogía;
Tiene un vaso de agua que está medio lleno y necesita rellenarlo.
La primera forma de hacerlo es tomando un vaso nuevo, llenándolo hasta la mitad con agua de un grifo y luego usando este segundo vaso medio lleno para rellenar el vaso. Hace esto cada vez que necesita rellenar su vaso.
La segunda forma de tomar su vaso medio lleno y simplemente llenarlo con agua directamente del grifo.
Al final del día, tendría que limpiar más vasos si elige elegir un vaso nuevo cada vez que necesite rellenarlo.
Lo mismo se aplica al operador de pala y al operador más igual. Además, el operador igual elige un nuevo 'vaso' cada vez que necesita rellenar su vaso, mientras que el operador de la pala solo toma el mismo vaso y lo rellena. Al final del día, más colección de 'vidrio' para el operador igual de Plus.
fuente
Esta es una vieja pregunta, pero acabo de encontrarla y no estoy completamente satisfecho con las respuestas existentes. Hay muchos puntos buenos acerca de que la pala << es más rápida que la concatenación + =, pero también hay una consideración semántica.
La respuesta aceptada de @noodl muestra que << modifica el objeto existente en su lugar, mientras que + = crea un nuevo objeto. Por lo tanto, debe tener en cuenta si desea que todas las referencias a la cadena reflejen el nuevo valor, o si desea dejar solo las referencias existentes y crear un nuevo valor de cadena para usar localmente. Si necesita todas las referencias para reflejar el valor actualizado, debe usar <<. Si desea dejar solo otras referencias, entonces necesita usar + =.
Un caso muy común es que solo hay una única referencia a la cadena. En este caso, la diferencia semántica no importa y es natural preferir << debido a su velocidad.
fuente
Debido a que es más rápido / no crea una copia de la cadena <-> el recolector de basura no necesita ejecutarse.
fuente
malloc
/free
. Además, algunas implementaciones más modernas de Ruby probablemente optimizarán la asignación de objetos y la concatenación de cadenas por completo. OTOH, la mutación de objetos es terrible para el rendimiento de GC.Si bien la mayoría de las respuestas
+=
son más lentas porque crea una nueva copia, ¡es importante tener en cuenta eso+=
y<<
no son intercambiables! Desea usar cada uno en diferentes casos.El uso
<<
también alterará las variables a las que se apuntab
. Aquí también mutamosa
cuando no queremos hacerlo.Debido a que
+=
hace una nueva copia, también deja las variables que la señalan sin cambios.¡Comprender esta distinción puede ahorrarle muchos dolores de cabeza cuando se trata de bucles!
fuente
Si bien no es una respuesta directa a su pregunta, ¿por qué The Fully Upturned Bin siempre ha sido uno de mis artículos favoritos de Ruby? También contiene información sobre cadenas con respecto a la recolección de basura.
fuente