Ich fange gerade an, Ruby zu lernen (erstmaliges Programmieren) und habe eine grundlegende syntaktische Frage in Bezug auf Variablen und verschiedene Arten, Code zu schreiben.
Chris Pines "Learn to Program" brachte mir bei, ein grundlegendes Programm wie dieses zu schreiben ...
num_cars_again= 2
puts 'I own ' + num_cars_again.to_s + ' cars.'
Das ist in Ordnung, aber dann bin ich über das Tutorial auf ruby.learncodethehardway.com gestolpert und habe gelernt, genau das gleiche Programm wie dieses zu schreiben ...
num_cars= 2
puts "I own #{num_cars} cars."
Beide geben dasselbe aus, aber Option 2 ist offensichtlich ein viel kürzerer Weg, dies zu tun.
Gibt es einen bestimmten Grund, warum ich ein Format über dem anderen verwenden sollte?
Antworten:
Wann immer TIMTOWTDI (es gibt mehr als einen Weg, dies zu tun), sollten Sie nach den Vor- und Nachteilen suchen. Verwenden von "String-Interpolation" (die zweite) anstelle von "String-Verkettung" (die erste):
Vorteile:
to_s
nach IhnenNachteile:
to_s
nach Ihnen (vielleicht dachten Sie, Sie hätten eine Zeichenfolge, und dieto_s
Darstellung entspricht nicht Ihren Wünschen und verbirgt die Tatsache, dass es sich nicht um eine Zeichenfolge handelt)."
zur Begrenzung Ihrer Zeichenfolge anstelle von'
(möglicherweise haben Sie die Gewohnheit'
, eine Zeichenfolge zu verwenden, oder Sie haben zuvor eine Zeichenfolge damit eingegeben und müssen sie erst später verwenden, um die Zeichenfolgeninterpolation zu verwenden)quelle
to_s
das Ergebnis aufzurufen und es in die Mitte einer Zeichenfolge einzufügen" . Wenn man etwas Neues lernt, gibt es oft Variationen zwischen "der einfach zu verstehenden Art" und "der Art und Weise, wie die Profis es tun".to_s
. Ja, für diejenigen von uns, die Typen und Konvertierungen verstehen, ist dies eine Annehmlichkeit. Für einen neuen Programmierer ist es jedoch sehr wichtig, diese Konzepte zu verstehen.Sowohl Interpolation als auch Konkatination haben ihre eigenen Stärken und Schwächen. Im Folgenden habe ich einen Benchmark angegeben, der deutlich zeigt, wo die Konkatination und die Interpolation verwendet werden sollen.
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
Und unten ist das Benchmark-Ergebnis
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) --------------------------------------------------
Fazit
Wenn Zeichenfolgen bereits definiert sind und sicher sind, dass sie niemals keine Konkatination verwenden, verwenden Sie die Interpolation. Verwenden Sie eine geeignete, die zu einer besseren Leistung führt als eine, die leicht einzurücken ist.
quelle
interpolation
ist schneller alsconcatenation
in beiden Fällen. Ich konnte hier aufgrund der Längenbeschränkung des Kommentars keine Ergebnisse einfügen, aber Sie können es selbst versuchen."#{firstname} #{middlename} #{lastname}"
wahrscheinlich verglichen werden solltenfirstname + " " + middlename + " " + lastname
, nichtfirstname + middlename + lastname
(Concat auf 5 Strings vs. 3 Strings)"#{firstname} #{middlename} #{lastname}"
dieconcatination
Interpolation immer erheblich schneller ist , wenn ich Ihren Benchmark ändere, um sie vergleichbar zu machen (indem Sie entweder die inneren Leerzeichen in den Fällen entfernen oder Leerzeichen zu den Fällen hinzufügen ) (zumindest unter Verwendung von Ruby 2.6.3 unter Mac OS X).@ user1181898 - IMHO, weil es einfacher ist zu sehen, was passiert. Bei @ Phrogz ruft die String-Interpolation automatisch die to_s für Sie auf. Als Anfänger müssen Sie sehen, was "unter der Haube" passiert, damit Sie das Konzept lernen, anstatt nur auswendig zu lernen.
Stellen Sie sich vor, Sie lernen Mathematik. Sie lernen den "langen" Weg, um die Konzepte zu verstehen, sodass Sie Verknüpfungen verwenden können, sobald Sie tatsächlich wissen, was Sie tun. Ich spreche aus Erfahrung b / c Ich bin noch nicht so fortgeschritten in Ruby, aber ich habe genug Fehler gemacht, um die Leute zu beraten, was sie nicht tun sollen. Hoffe das hilft.
quelle
Wenn Sie eine Zeichenfolge als Puffer verwenden, habe ich festgestellt, dass die Verwendung von concatenation (
String#concat
) schneller ist.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
Ergebnisse:
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
Vermutlich würde die Interpolation eine temporäre Zeichenfolge erzeugen, weshalb sie langsamer ist.
quelle
Hier ist ein vollständiger Benchmark, der auch vergleicht
Kernel#format
undString#+
wie ich weiß, alle Methoden zur Konstruktion dynamischer Strings in Rubin 🤔require 'benchmark/ips' firstname = 'soundarapandian' middlename = 'rathinasamy' lastname = 'arumugam' FORMAT_STR = 'Mr. %<firstname>s %<middlename>s %<lastname>s aka soundar' Benchmark.ips do |x| x.report("String\#<<") do |i| str = String.new str << 'Mr. ' << firstname << ' ' << middlename << ' ' << lastname << ' aka soundar' end x.report "String\#+" do 'Mr. ' + firstname + ' ' + middlename + ' ' + lastname + ' aka soundar' end x.report "format" do format(FORMAT_STR, firstname: firstname, middlename: middlename, lastname: lastname) end x.report("String interpolate") do |i| "Mr. #{firstname} #{middlename} #{lastname} aka soundar" end x.compare! end
Und Ergebnisse für Ruby 2.6.5
Warming up -------------------------------------- String#<< 94.597k i/100ms String#+ 75.512k i/100ms format 73.269k i/100ms String interpolate 164.005k i/100ms Calculating ------------------------------------- String#<< 91.385B (±16.9%) i/s - 315.981B String#+ 905.389k (± 4.2%) i/s - 4.531M in 5.013725s format 865.746k (± 4.5%) i/s - 4.323M in 5.004103s String interpolate 161.694B (±11.3%) i/s - 503.542B Comparison: String interpolate: 161693621120.0 i/s String#<<: 91385051886.2 i/s - 1.77x slower String#+: 905388.7 i/s - 178590.27x slower format: 865745.8 i/s - 186768.00x slower
quelle