Конкатенация строк и интерполяция в Ruby
Я только начинаю изучать Ruby (first time programming), и у меня есть основной синтаксический вопрос относительно переменных и различных способов написания кода.
Крис Пайн "учись программировать" научил меня писать подобные программы...
num_cars_again= 2
puts 'I own ' + num_cars_again.to_s + ' cars.'
это нормально, но потом я наткнулся на учебник по ruby.learncodethehardway.com и научили писать точно такую же программу, как эта...
num_cars= 2
puts "I own #{num_cars} cars."
Они оба выводят одно и то же вещь, но, очевидно, вариант 2-это гораздо более короткий способ сделать это.
есть ли какая-то особая причина, почему я должен использовать одного формата над другим?
4 ответа:
всякий раз, когда TIMTOWTDI (есть более чем один способ сделать это), вы должны искать плюсы и минусы. Использование" Строковой интерполяции "(второй) вместо "конкатенации строк" (первый):
плюсы:
- меньше ввода
- автоматически называет
to_s
для вас- более идиоматично в сообществе Ruby
- быстрее выполнить во время время работы
плюсы:
- автоматически называет
to_s
для вас (может быть, вы думали, что у вас есть строка, иto_s
представление-это не то, что вы хотели, и скрывает тот факт, что это была не строка)- требует, чтобы вы использовать
"
чтобы разделить строку вместо'
(возможно, у вас есть привычка использовать'
, или вы ранее набрали строку с помощью этого и только позже необходимо использовать строку интерполяция)
и интерполяция, и конкатинация имеют свою силу и слабость. Ниже я дал Эталон, который четко демонстрирует, где использовать конкатинацию и где использовать интерполяцию.
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
и ниже приведен результат теста
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) --------------------------------------------------
вывод
Если строки уже определены и уверены, что они никогда не будут равны нулю, используйте конкатинацию, иначе используйте интерполяцию.Используйте соответствующий, который приведет к лучшей производительности, чем один который легко отступить.
@user1181898-IMHO, это потому, что легче увидеть, что происходит. К точке @Phrogz, строка интерполяции автоматически вызывает to_s для вас. Как новичок, вам нужно увидеть, что происходит "под капотом", чтобы вы изучили концепцию, а не просто учились наизусть.
подумайте об этом, как изучение математики. Вы изучаете "длинный" путь, чтобы понять концепции, чтобы вы могли срезать путь, как только вы действительно знаете, что делаете. Я говорю из опыта b / c я еще не настолько продвинулся в Ruby, но я сделал достаточно ошибок, чтобы советовать людям, что не делать. Надеюсь, это поможет.
Если вы используете строку в качестве буфера, я обнаружил, что с помощью конкатенации (
String#concat
), чтобы быть быстрее.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
результаты:
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
на предположение, я бы сказал, что интерполяция генерирует временную строку, поэтому она медленнее.