una str que manejo interpolar example contar concatenar caracteres cadenas cadena ruby string-concatenation

str - manejo de cadenas en ruby



Concatenación de cuerdas en Ruby (11)

Estoy buscando una forma más elegante de concatenar cadenas en Ruby.

Tengo la siguiente línea:

source = "#{ROOT_DIR}/" << project << "/App.config"

¿Hay una manera más agradable de hacer esto?

Y para eso, ¿cuál es la diferencia entre << y + ?


Aquí hay más formas de hacer esto:

"String1" + "String2" "#{String1} #{String2}" String1<<String2

Y así ...


Aquí hay otro punto de referencia inspirado por esta esencia . Compara la concatenación ( + ), la adición ( << ) y la interpolación ( #{} ) para cadenas dinámicas y predefinidas.

require ''benchmark'' # we will need the CAPTION and FORMAT constants: include Benchmark count = 100_000 puts "Dynamic strings" Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm| bm.report("concat") { count.times { 11.to_s + ''/'' + 12.to_s } } bm.report("append") { count.times { 11.to_s << ''/'' << 12.to_s } } bm.report("interp") { count.times { "#{11}/#{12}" } } end puts "/nPredefined strings" s11 = "11" s12 = "12" Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm| bm.report("concat") { count.times { s11 + ''/'' + s12 } } bm.report("append") { count.times { s11 << ''/'' << s12 } } bm.report("interp") { count.times { "#{s11}/#{s12}" } } end

salida:

Dynamic strings user system total real concat 0.050000 0.000000 0.050000 ( 0.047770) append 0.040000 0.000000 0.040000 ( 0.042724) interp 0.050000 0.000000 0.050000 ( 0.051736) Predefined strings user system total real concat 0.030000 0.000000 0.030000 ( 0.024888) append 0.020000 0.000000 0.020000 ( 0.023373) interp 3.160000 0.160000 3.320000 ( 3.311253)

Conclusión: la interpolación en RMN es pesada.


Déjame mostrarte toda mi experiencia con eso.

Tuve una consulta que devolvió 32k de registros, por cada registro que llamé a un método para formatear ese registro de base de datos en una cadena con formato y luego concatenarla en una Cadena que al final de todo este proceso se convertirá en un archivo en el disco.

Mi problema fue que según el registro, alrededor de 24k, el proceso de concatenar el String se convirtió en un dolor.

Estaba haciendo eso usando el operador regular ''+''.

Cuando cambié a ''<<'' fue como magia. Fue realmente rápido.

Entonces, recordé mis viejos tiempos, más o menos 1998, cuando estaba usando Java y concatenando String usando ''+'' y cambié de String a StringBuffer (y ahora nosotros, el desarrollador de Java tenemos StringBuilder).

Creo que el proceso de + / << en el mundo de Ruby es el mismo que el de + / StringBuilder.append en el mundo de Java.

La primera reasigna todo el objeto en la memoria y la otra simplemente apunta a una nueva dirección.


El operador + es la opción de concatenación normal, y es probablemente la forma más rápida de concatenar cadenas.

La diferencia entre + y << es que << cambia el objeto en su lado izquierdo, y + no lo hace.

irb(main):001:0> s = ''a'' => "a" irb(main):002:0> s + ''b'' => "ab" irb(main):003:0> s => "a" irb(main):004:0> s << ''b'' => "ab" irb(main):005:0> s => "ab"


La concatenación que dices? ¿Qué #concat método #concat entonces?

a = ''foo'' a.object_id #=> some number a.concat ''bar'' #=> foobar a.object_id #=> same as before -- string a remains the same object

Para ser justos, concat se presenta como << .


Preferiría usar Pathname:

require ''pathname'' # pathname is in stdlib Pathname(ROOT_DIR) + project + ''App.config''

sobre << y + de documentos de ruby:

+ : Devuelve una nueva cadena que contiene other_str concatenada a str

<< : Concatena el objeto dado a str. Si el objeto es un Fixnum entre 0 y 255, se convierte en un carácter antes de la concatenación.

así que la diferencia está en lo que se convierte en el primer operando ( << hace cambios en su lugar, + devuelve una nueva cadena, por lo que es más pesada la memoria) y qué ocurrirá si el primer operando es Fixnum ( << se agregará como si fuera un carácter con código igual ese número, + generará error)


Puede usar el operador + o << , pero en ruby .concat función es la más preferible, ya que es mucho más rápida que otros operadores. Puedes usarlo como.

source = "#{ROOT_DIR}/".concat(project.concat.("/App.config"))


Puedes hacerlo de varias maneras:

  1. Como se muestra con << pero esa no es la forma habitual.
  2. Con interpolación de cuerdas.

    source = "#{ROOT_DIR}/#{project}/App.config"

  3. con +

    source = "#{ROOT_DIR}/" + project + "/App.config"

El segundo método parece ser más eficiente en términos de memoria / velocidad de lo que he visto (aunque no se ha medido). Los tres métodos arrojarán un error constante sin inicializar cuando ROOT_DIR es nulo.

Cuando se trata de File.join acceso, es posible que desee utilizar File.join para evitar problemas con el separador de ruta de acceso.

Al final, es cuestión de gustos.


Si solo está concatenando rutas, puede usar el método File.join de Ruby.

source = File.join(ROOT_DIR, project, ''App.config'')


Ya que esta es una ruta probablemente usaría array y uniría:

source = [ROOT_DIR, project, ''App.config''] * ''/''


de http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/

Usar << aka concat es mucho más eficiente que += , ya que este último crea un objeto temporal y reemplaza el primer objeto con el nuevo objeto.

require ''benchmark'' N = 1000 BASIC_LENGTH = 10 5.times do |factor| length = BASIC_LENGTH * (10 ** factor) puts "_" * 60 + "/nLENGTH: #{length}" Benchmark.bm(10, ''+= VS <<'') do |x| concat_report = x.report("+=") do str1 = "" str2 = "s" * length N.times { str1 += str2 } end modify_report = x.report("<<") do str1 = "s" str2 = "s" * length N.times { str1 << str2 } end [concat_report / modify_report] end end

salida:

____________________________________________________________ LENGTH: 10 user system total real += 0.000000 0.000000 0.000000 ( 0.004671) << 0.000000 0.000000 0.000000 ( 0.000176) += VS << NaN NaN NaN ( 26.508796) ____________________________________________________________ LENGTH: 100 user system total real += 0.020000 0.000000 0.020000 ( 0.022995) << 0.000000 0.000000 0.000000 ( 0.000226) += VS << Inf NaN NaN (101.845829) ____________________________________________________________ LENGTH: 1000 user system total real += 0.270000 0.120000 0.390000 ( 0.390888) << 0.000000 0.000000 0.000000 ( 0.001730) += VS << Inf Inf NaN (225.920077) ____________________________________________________________ LENGTH: 10000 user system total real += 3.660000 1.570000 5.230000 ( 5.233861) << 0.000000 0.010000 0.010000 ( 0.015099) += VS << Inf 157.000000 NaN (346.629692) ____________________________________________________________ LENGTH: 100000 user system total real += 31.270000 16.990000 48.260000 ( 48.328511) << 0.050000 0.050000 0.100000 ( 0.105993) += VS << 625.400000 339.800000 NaN (455.961373)