eingabe - ruby zahlen addieren




String-Verkettung in Ruby (7)

Ich suche nach einer eleganteren Art, Strings in Ruby zu verketten.

Ich habe folgende Zeile:

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

Gibt es einen schöneren Weg, dies zu tun?

Und was ist der Unterschied zwischen << und + ?


Da dies ein Pfad ist, würde ich wahrscheinlich Array und Join verwenden:

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

Der Operator + ist die normale Verkettungsoption und wahrscheinlich der schnellste Weg zum Verketten von Strings.

Der Unterschied zwischen + und << ist, dass << das Objekt auf der linken Seite ändert und + nicht.

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"

Hier sind weitere Möglichkeiten, dies zu tun:

"String1" + "String2"

"#{String1} #{String2}"

String1<<String2

Und so weiter ...


Ich würde lieber den Pfadnamen verwenden:

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

über << und + von Ruby Docs:

+ : Gibt einen neuen String zurück, der other_str enthält, der mit str verkettet ist

<< : Verkettet das gegebene Objekt mit str. Wenn das Objekt eine Fixnum zwischen 0 und 255 ist, wird es vor der Verkettung in ein Zeichen konvertiert.

Der Unterschied besteht darin, was zum ersten Operanden wird ( << macht Änderungen an Ort und Stelle, + liefert neuen String, so dass es Speicher schwerer ist) und was sein wird, wenn der erste Operand Fixnum ist ( << wird hinzugefügt, als wäre es ein Zeichen mit Code gleich diese Zahl, + wird Fehler auslösen)


Sie können das auf verschiedene Arten tun:

  1. Wie Sie mit << gezeigt haben, ist das nicht der übliche Weg
  2. Mit String-Interpolation

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

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

Die zweite Methode scheint im Hinblick auf Gedächtnis / Geschwindigkeit effizienter zu sein als das, was ich gesehen habe (nicht gemessen). Alle drei Methoden verursachen einen nicht initialisierten konstanten Fehler, wenn ROOT_DIR gleich null ist.

Wenn Sie sich mit Pfadnamen befassen, möchten Sie möglicherweise File.join , um zu File.join , dass Sie mit dem Trennzeichen für Pfadnamen File.join .

Am Ende ist es Geschmackssache.


Verkettung, sagst du? Wie wäre es mit #concat Methode dann?

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

In aller Fairness ist concat Aliasing als << .


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

Die Verwendung von << aka concat ist weitaus effizienter als += , da letztere ein temporäres Objekt erstellt und das erste Objekt mit dem neuen Objekt überschreibt.

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

Ausgabe:

____________________________________________________________
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)




string-concatenation