Konkatenacja łańcuchów w Ruby
Szukam bardziej eleganckiego sposobu łączenia sznurków w Ruby.
Mam następujący wiersz:
source = "#{ROOT_DIR}/" << project << "/App.config"
Czy jest na to lepszy sposób?
I jaka jest różnica między <<
A +
?
10 answers
Możesz to zrobić na kilka sposobów:]}
- Jak pokazałeś z
<<
ale to nie jest zwykły sposób -
Z interpolacją ciągu
source = "#{ROOT_DIR}/#{project}/App.config"
-
Z
+
source = "#{ROOT_DIR}/" + project + "/App.config"
Druga metoda wydaje się być bardziej efektywna pod względem pamięci/szybkości z tego, co widziałem (ale nie mierzona). Wszystkie trzy metody wywołają niezainicjowany stały błąd, gdy ROOT_DIR jest zerowy.
Gdy masz do czynienia z nazwami ścieżek, możesz użyć File.join
aby uniknąć bałaganu z separatorem pathname.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-01 20:14:57
Operator +
jest normalnym wyborem konkatenacji i jest prawdopodobnie najszybszym sposobem łączenia łańcuchów.
Różnica między +
i <<
jest taka, że <<
zmienia obiekt po lewej stronie, a +
NIE.
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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-27 02:52:15
Jeśli tylko łączysz ścieżki, możesz użyć własnego pliku Rubiego.metoda join.
source = File.join(ROOT_DIR, project, 'App.config')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 13:22:32
Z http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/
Użycie <<
aka concat
jest znacznie wydajniejsze niż +=
, ponieważ ten ostatni tworzy obiekt czasowy i nadpisuje pierwszy obiekt nowym.
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
Wyjście:
____________________________________________________________
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-01 13:02:46
Ponieważ jest to ścieżka prawdopodobnie użyłbym array I join:
source = [ROOT_DIR, project, 'App.config'] * '/'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 13:14:23
Oto kolejny benchmark zainspirowany tym gist . Porównuje concatenation (+
), appending (<<
) i interpolation (#{}
) dla dynamicznych i predefiniowanych łańcuchów.
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
Wyjście:
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)
Wniosek: interpolacja w MRI jest ciężka.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-13 18:06:02
Wolałbym użyć Pathname:
require 'pathname' # pathname is in stdlib
Pathname(ROOT_DIR) + project + 'App.config'
O <<
i +
z Ruby docs:
+
: zwraca new łańcuch zawierający other_str skonkatenowany do str
<<
: Konkatenuje dany obiekt do str. Jeśli obiekt jest Fixnum z zakresu od 0 do 255, jest konwertowany na znak przed konkatenacją.
Więc różnica polega na tym, co staje się pierwszym operandem (<<
wprowadza zmiany w miejscu, +
zwraca nowy ciąg, więc jest to pamięć cięższa) i co będzie jeśli pierwszym operandem jest Fixnum (<<
doda tak, jakby był to znak o kodzie równym tej liczbie, +
wywoła błąd)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-27 02:53:14
Pozwól, że pokażę Ci całe moje doświadczenie z tym.
Miałem zapytanie, które zwróciło 32K rekordów, dla każdego rekordu wywołałem metodę sformatowania tego rekordu bazy danych do sformatowanego łańcucha i następnie połączyłem go w łańcuch, który pod koniec całego tego procesu zamieni się w plik na dysku.
Moim problemem było to, że przy zapisie idzie, około 24k, proces łączenia struny zwrócił się ból.
Robiłem to używając zwykłego"+" centrala.
Kiedy zmieniłem na '
Tak więc, przypomniałem sobie moje stare czasy-tak jakby 1998 - kiedy używałem Javy i łączyłem String za pomocą ' + ' i zmieniałem z String Na StringBuffer (a teraz my, Java developer mamy StringBuilder).
Uważam, że proces + /
Pierwszy zapisuje cały obiekt w pamięci, a drugi tylko wskazuje pod nowy adres.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-03 20:11:33
Mówisz o konkatenacji? A może metoda #concat
?
a = 'foo'
a.object_id #=> some number
a.concat 'bar' #=> foobar
a.object_id #=> same as before -- string a remains the same object
W całej sprawiedliwości, {[2] } jest aliased jako <<
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-12 03:48:00
Oto więcej sposobów, aby to zrobić:
"String1" + "String2"
"#{String1} #{String2}"
String1<<String2
I tak dalej ...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 20:50:49