La concatenación de cadenas vs interpolación en Rubí


Estoy empezando a aprender Ruby (programación por primera vez), y tengo una pregunta sintáctica básica con respecto a las variables, y varias formas de escribir código.

"Aprender a programar" de Chris Pine me enseñó a escribir un programa básico como este...

num_cars_again= 2
puts 'I own ' + num_cars_again.to_s + ' cars.'

Esto está bien, pero luego me topé con el tutorial sobre ruby.learncodethehardway.com y se le enseñó a escribir exactamente el mismo programa como este...

num_cars= 2
puts "I own #{num_cars} cars."

Ambos producen lo mismo, pero obviamente la opción 2 es una forma mucho más corta de hacerlo.

¿Hay alguna razón en particular por la que deba usar un formato sobre el otro?

Author: mrlee, 2012-04-09

4 answers

Siempre que TIMTOWTDI (hay más de una manera de hacerlo), debe buscar los pros y los contras. Usando "interpolación de cadenas" (la segunda) en lugar de "concatenación de cadenas" (la primera):

Pros:

  • Es menos escribir
  • Llama automáticamente a to_s para usted
  • Más idiomático dentro de la comunidad Ruby
  • Más rápido de lograr durante el tiempo de ejecución

Contras:

  • Llama automáticamente a to_s para usted (tal vez pensaste que tenías una cadena, y la representación to_s no es lo que querías, y oculta el hecho de que no era una cadena)
  • Requiere que uses " para delimitar tu cadena en lugar de ' (tal vez tengas la costumbre de usar ', o escribiste previamente una cadena usando eso y solo más tarde necesitaste usar interpolación de cadenas)
 66
Author: Phrogz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-09 17:19:21

Tanto la interpolación como la concatinación tienen su propia fuerza y debilidad. A continuación di un punto de referencia que demuestra claramente dónde usar la concatinación y dónde usar la interpolación.

require 'benchmark'

iterations = 1_00_000
firstname = 'soundarapandian'
middlename = 'rathinasamy'
lastname = 'arumugam'

puts 'With dynamic new strings'
puts '===================================================='
5.times do
  Benchmark.bm(10) do |benchmark|
    benchmark.report('concatination') do
      iterations.times do
        'Mr. ' + firstname + middlename + lastname + ' aka soundar'
      end
    end

    benchmark.report('interpolaton') do
      iterations.times do
        "Mr. #{firstname} #{middlename} #{lastname} aka soundar"
      end
    end
  end
  puts '--------------------------------------------------'
end

puts 'With predefined strings'
puts '===================================================='
5.times do
  Benchmark.bm(10) do |benchmark|
    benchmark.report('concatination') do
      iterations.times do
        firstname + middlename + lastname
      end
    end

    benchmark.report('interpolaton') do
      iterations.times do
        "#{firstname} #{middlename} #{lastname}"
      end
    end
  end
  puts '--------------------------------------------------'
end

Y a continuación se muestra el resultado de referencia

Without predefined strings
====================================================
                 user     system      total        real
concatination  0.170000   0.000000   0.170000 (  0.165821)
interpolaton  0.130000   0.010000   0.140000 (  0.133665)
--------------------------------------------------
                 user     system      total        real
concatination  0.180000   0.000000   0.180000 (  0.180410)
interpolaton  0.120000   0.000000   0.120000 (  0.125051)
--------------------------------------------------
                 user     system      total        real
concatination  0.140000   0.000000   0.140000 (  0.134256)
interpolaton  0.110000   0.000000   0.110000 (  0.111427)
--------------------------------------------------
                 user     system      total        real
concatination  0.130000   0.000000   0.130000 (  0.132047)
interpolaton  0.120000   0.000000   0.120000 (  0.120443)
--------------------------------------------------
                 user     system      total        real
concatination  0.170000   0.000000   0.170000 (  0.170394)
interpolaton  0.150000   0.000000   0.150000 (  0.149601)
--------------------------------------------------
With predefined strings
====================================================
                 user     system      total        real
concatination  0.070000   0.000000   0.070000 (  0.067735)
interpolaton  0.100000   0.000000   0.100000 (  0.099335)
--------------------------------------------------
                 user     system      total        real
concatination  0.060000   0.000000   0.060000 (  0.061955)
interpolaton  0.130000   0.000000   0.130000 (  0.127011)
--------------------------------------------------
                 user     system      total        real
concatination  0.090000   0.000000   0.090000 (  0.092136)
interpolaton  0.110000   0.000000   0.110000 (  0.110224)
--------------------------------------------------
                 user     system      total        real
concatination  0.080000   0.000000   0.080000 (  0.077587)
interpolaton  0.110000   0.000000   0.110000 (  0.112975)
--------------------------------------------------
                 user     system      total        real
concatination  0.090000   0.000000   0.090000 (  0.088154)
interpolaton  0.140000   0.000000   0.140000 (  0.135349)
--------------------------------------------------

Conclusión

Si las cadenas ya están definidas y seguro que nunca serán nil use concatinación, sino use interpolación.Utilice uno apropiado que resultará en un mejor rendimiento que uno que es fácil de sangrar.

 8
Author: Soundar Rathinasamy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-11 11:32:17

@user1181898 - En mi humilde opinión, es porque es más fácil ver lo que está sucediendo. Para el punto de @Phrogz, la interpolación de cadenas llama automáticamente a los to_s por usted. Como principiante, necesitas ver lo que está sucediendo "bajo el capó" para que aprendas el concepto en lugar de solo aprender de memoria.

Piense en ello como aprender matemáticas. Aprendes el camino "largo" para entender los conceptos de modo que puedas tomar atajos una vez que realmente sepas lo que estás haciendo. Yo hablo desde experiencia b / c Todavía no estoy tan avanzado en Ruby, pero he cometido suficientes errores como para aconsejar a la gente sobre qué no hacer. Espero que esto ayude.

 3
Author: Martin Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-09 17:01:21

Si estás usando una cadena como búfer, encontré que usar concatenación (String#concat) es más rápido.

require 'benchmark/ips'

puts "Ruby #{RUBY_VERSION} at #{Time.now}"
puts

firstname = 'soundarapandian'
middlename = 'rathinasamy'
lastname = 'arumugam'

Benchmark.ips do |x|
    x.report("String\#<<") do |i|
        buffer = String.new

        while (i -= 1) > 0
            buffer << 'Mr. ' << firstname << middlename << lastname << ' aka soundar'
        end
    end

    x.report("String interpolate") do |i|
        buffer = String.new

        while (i -= 1) > 0
            buffer << "Mr. #{firstname} #{middlename} #{lastname} aka soundar"
        end
    end

    x.compare!
end

Resultados:

Ruby 2.3.1 at 2016-11-15 15:03:57 +1300

Warming up --------------------------------------
           String#<<   230.615k i/100ms
  String interpolate   234.274k i/100ms
Calculating -------------------------------------
           String#<<      2.345M (± 7.2%) i/s -     11.761M in   5.041164s
  String interpolate      1.242M (± 5.4%) i/s -      6.325M in   5.108324s

Comparison:
           String#<<:  2344530.4 i/s
  String interpolate:  1241784.9 i/s - 1.89x  slower

En una conjetura, yo diría que la interpolación genera una cadena temporal, por lo que es más lenta.

 1
Author: ioquatix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-15 02:08:02