루비의 문자열 연결
루비에서 줄을 연결하는 더 우아한 방법을 찾고 있습니다.
다음과 같은 대사가 있습니다.
source = "#{ROOT_DIR}/" << project << "/App.config"
이것을 하는 더 좋은 방법이 있습니까?
그리고 그 문제와 관련하여, 무엇이 다른가?<<
그리고.+
?
여러 가지 방법으로 이 작업을 수행할 수 있습니다.
- 에서 보여드린 바와 같이
<<
하지만 그것은 일반적인 방법이 아닙니다. 문자열 보간 포함
source = "#{ROOT_DIR}/#{project}/App.config"
와 함께
+
source = "#{ROOT_DIR}/" + project + "/App.config"
두 번째 방법은 제가 본 것보다 메모리/속도 측면에서 더 효율적인 것 같습니다(그러나 측정되지는 않았습니다).ROOT_DIR이 0인 경우 세 가지 메서드 모두 초기화되지 않은 상수 오류를 발생시킵니다.
이름을 는 경로이처때리다사수있용다습니할음을름할을다있▁want를 하는 것이 .File.join
경로 이름 구분 기호와 혼동하지 않도록 합니다.
결국, 그것은 취향의 문제입니다.
그+
연산자는 일반적인 연결 선택이며 문자열을 연결하는 가장 빠른 방법일 것입니다.
의 +
그리고.<<
은 것은입니다.<<
왼쪽에서 개체를 변경합니다.+
안 합니다.
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"
경로만 연결하는 경우 Ruby의 File.join 메서드를 사용할 수 있습니다.
source = File.join(ROOT_DIR, project, 'App.config')
http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/ 에서
용사를 합니다.<<
카아concat
효훨입다니보다 훨씬 입니다.+=
후자가 시간적 객체를 생성하고 첫 번째 객체를 새 객체로 재정의하기 때문입니다.
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
출력:
____________________________________________________________
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)
이 경로를 통해 어레이를 사용하고 참여할 수 있습니다.
source = [ROOT_DIR, project, 'App.config'] * '/'
여기 이 요점에서 영감을 얻은 또 다른 벤치마크가 있습니다.연결을 비교합니다(+
(), 추가(()<<
( ) 및간보(보()#{}
및 된 문자열에 됩니다.는 동적 및 미리 정의된 문자열입니다.
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
출력:
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)
결론: MRI의 보간은 무겁습니다.
경로 이름을 사용하는 것이 좋습니다.
require 'pathname' # pathname is in stdlib
Pathname(ROOT_DIR) + project + 'App.config'
해서대.<<
그리고.+
루비 문서에서:
+
str에 연결된 other_str을 포함하는 새 문자열을 반환합니다.
<<
지정된 개체를 str에 연결합니다.개체가 0에서 255 사이의 수정 번호인 경우 연결 전 문자로 변환됩니다.
첫 피연산자가 .<<
제자리에서 변화를 일으킵니다.+
새더 . 첫. 그리고 첫 번째 피연산자가 Fixnum(<<
그 숫자와 같은 코드를 가진 문자인 것처럼 추가할 것입니다.+
error)는 오류를 발생시킵니다.
제 경험을 모두 보여드리겠습니다.
32k개의 레코드를 반환하는 쿼리가 있었습니다. 각 레코드에 대해 데이터베이스 레코드를 형식화된 문자열로 포맷하고 이를 문자열로 연결하는 방법을 호출했습니다. 이 모든 프로세스가 끝나면 디스크의 파일로 변환됩니다.
제 문제는 기록에 따르면 약 24k에 String을 연결하는 과정이 고통스럽게 변했다는 것입니다.
저는 일반적인 '+' 연산자를 사용하여 그것을 하고 있었습니다.
제가 '<<'로 바꾸었을 때는 마법 같았습니다.진짜 빨랐어요.
그래서, 저는 제가 Java를 사용하고 '+'를 사용하여 String을 연결하고 StringBuffer로 변경했던 예전의 1998년의 일을 기억했습니다. (그리고 지금은 Java 개발자가 StringBuilder를 가지고 있습니다.)
루비 월드에서 + / <<의 프로세스는 자바 월드에서 + / StringBuilder.append와 동일하다고 생각합니다.
첫 번째는 메모리의 전체 개체를 재할당하고 다른 하나는 새 주소를 가리키기만 합니다.
연결이라고요?어때.#concat
그럼 방법은?
a = 'foo'
a.object_id #=> some number
a.concat 'bar' #=> foobar
a.object_id #=> same as before -- string a remains the same object
공평하게 말하자면,concat
에일리어스가 지정됨<<
.
이를 위한 추가 방법은 다음과 같습니다.
"String1" + "String2"
"#{String1} #{String2}"
String1<<String2
등등...
사용할 수도 있습니다.%
다음과 같이:
source = "#{ROOT_DIR}/%s/App.config" % project
이 접근 방식은 다음과 같이 작동합니다.'
따옴표(단일)도 함께 표시합니다.
문자열 정의에서 직접 연결할 수 있습니다.
nombre_apellido = "#{customer['first_name']} #{customer['last_name']} #{order_id}"
사용할 수 있습니다.+
또는<<
연산자, 그러나 루비로 표시됨.concat
함수는 다른 연산자보다 훨씬 빠르기 때문에 가장 선호되는 연산자입니다.이렇게 사용하시면 됩니다.
source = "#{ROOT_DIR}/".concat(project.concat("/App.config"))
상황이 중요합니다. 예를 들어 다음과 같습니다.
# this will not work
output = ''
Users.all.each do |user|
output + "#{user.email}\n"
end
# the output will be ''
puts output
# this will do the job
output = ''
Users.all.each do |user|
output << "#{user.email}\n"
end
# will get the desired output
puts output
첫 번째 예제에서는 다음과 연결됩니다.+
연산자가 업데이트하지 않습니다.output
객체, 그러나 두 번째 예에서,<<
운영자가 업데이트합니다.output
각 반복이 있는 개체입니다.위와 같은 상황에 대해서는<<
더 낫습니다.
당신의 특정한 경우를 위해 당신은 또한 사용할 수 있습니다.Array#join
문자열의 파일 경로 유형을 구성할 때:
string = [ROOT_DIR, project, 'App.config'].join('/')]
이는 여러 유형을 문자열로 자동 변환하는 효과가 있습니다.
['foo', :bar, 1].join('/')
=>"foo/bar/1"
Puppet의 경우:
$username = 'lala'
notify { "Hello ${username.capitalize}":
withpath => false,
}
언급URL : https://stackoverflow.com/questions/377768/string-concatenation-in-ruby
'programing' 카테고리의 다른 글
iPhone에서 프로그래밍 방식으로 메모리 사용량 검색 (0) | 2023.06.01 |
---|---|
Android에서 글꼴을 변경하는 방법 TextView 제품군 (0) | 2023.06.01 |
레일 모델, 뷰, 컨트롤러 및 도우미: 무엇이 가능합니까? (0) | 2023.06.01 |
UI 테이블 보기를 길게 누릅니다. (0) | 2023.06.01 |
테이블 크기 조정 방법UI 테이블 뷰의 머리글 뷰? (0) | 2023.06.01 |