루비에서 문자열을 만들 때 삽 연산자(<)가 플러스 기호(+=)보다 선호되는 이유는 무엇입니까?
저는 루비코안스를 통해 일하고 있습니다.
그test_the_shovel_operator_modifies_the_original_string
about_strings.rb의 Koan은 다음 주석을 포함합니다.
루비 프로그래머들은 문자열을 만들 때 플러스 등호 연산자(+=)보다 삽 연산자(<)를 선호하는 경향이 있습니다. 왜죠?
제 생각에는 속도가 필요한 것 같은데, 저는 삽 조작자를 더 빠르게 만드는 후드 아래의 행동을 이해할 수 없습니다.
누가 이 선호도 뒤에 있는 세부 사항을 설명해 주시겠습니까?
증명:
a = 'foo'
a.object_id #=> 2154889340
a << 'bar'
a.object_id #=> 2154889340
a += 'quux'
a.object_id #=> 2154742560
그렇게<<
새 문자열을 만드는 대신 원래 문자열을 변경합니다.그 이유는 루비로 되어있기 때문입니다.a += b
의 통사적 약어입니다.a = a + b
(다른 것도 마찬가지입니다.<op>=
연산자), 즉 과제입니다.반면에<<
의 별칭입니다.concat()
수신기가 제자리에 있는 상태로 바뀝니다.
성능 증명:
#!/usr/bin/env ruby
require 'benchmark'
Benchmark.bmbm do |x|
x.report('+= :') do
s = ""
10000.times { s += "something " }
end
x.report('<< :') do
s = ""
10000.times { s << "something " }
end
end
# Rehearsal ----------------------------------------
# += : 0.450000 0.010000 0.460000 ( 0.465936)
# << : 0.010000 0.000000 0.010000 ( 0.009451)
# ------------------------------- total: 0.470000sec
#
# user system total real
# += : 0.270000 0.010000 0.280000 ( 0.277945)
# << : 0.000000 0.000000 0.000000 ( 0.003043)
루비를 첫 프로그래밍 언어로 배우는 친구가 루비 코안스 시리즈에서 'Ruby'의 'Strings in Ruby'를 겪으며 똑같은 질문을 했습니다.저는 다음과 같은 비유를 사용하여 그에게 설명했습니다.
당신은 반쯤 채워진 물 한 잔을 가지고 있고 당신은 당신의 잔을 다시 채워야 합니다.
첫 번째 방법은 새 잔을 들고, 수도꼭지에서 물을 반쯤 채운 다음, 두 번째 반 잔을 사용하여 마시는 잔을 다시 채우는 것입니다.당신은 잔을 다시 채워야 할 때마다 이렇게 합니다.
두 번째 방법은 반 컵을 들고 수도꼭지에서 바로 물을 다시 채우는 것입니다.
결국, 만약 여러분이 잔을 다시 채울 필요가 있을 때마다 새로운 잔을 선택한다면, 여러분은 더 많은 잔을 청소해야 할 것입니다.
삽 조작자와 플러스 이퀄 조작자에게도 동일하게 적용됩니다.또한 동등한 작업자는 새 '유리'를 선택하고 삽 작업자는 동일한 유리를 사용하여 다시 채워야 합니다.마지막으로 Plus 등호 연산자를 위한 더 많은 '유리' 컬렉션을 제공합니다.
이것은 오래된 질문이지만, 저는 방금 우연히 발견했고 저는 기존의 답변에 완전히 만족하지 않습니다.삽 << 연결 +=보다 빠르다는 장점이 많지만 의미론적인 고려도 있습니다.
@prefl에서 받아들여진 답은 <<이 제자리에 있는 기존 객체를 수정하는 반면 +=는 새로운 객체를 생성한다는 것을 보여줍니다.따라서 문자열에 대한 모든 참조에 새 값을 반영할 것인지 아니면 기존 참조를 그대로 두고 로컬에서 사용할 새 문자열 값을 만들 것인지 고려해야 합니다.업데이트된 값을 반영하기 위해 모든 참조가 필요한 경우 <<을 사용해야 합니다.다른 참조를 그대로 두려면 +=를 사용해야 합니다.
문자열에 대한 참조가 하나뿐인 경우가 매우 일반적입니다.이 경우 의미적 차이는 중요하지 않으며 속도 때문에 <<을 선호하는 것은 당연합니다.
더 빠르기 때문에 / 가비지 수집기를 실행할 필요가 없는 문자열 <->의 복사본을 만들지 않습니다.
대부분의 대답은 다음과 같습니다.+=
복사본을 명심하는 것이 중요합니다.+=
그리고.<<
호환되지 않습니다!각 항목을 다른 경우에 사용하려고 합니다.
용사를 합니다.<<
는 또한 " 또가변변경됩다니수도는키리한▁that"를 가리키는 변수도 합니다.b
여기서 우리는 변이도 합니다.a
우리가 원하지 않을 때.
2.3.1 :001 > a = "hello"
=> "hello"
2.3.1 :002 > b = a
=> "hello"
2.3.1 :003 > b << " world"
=> "hello world"
2.3.1 :004 > a
=> "hello world"
ㅠㅠ+=
새 복사본을 만들고 이 복사본을 가리키는 변수도 변경되지 않습니다.
2.3.1 :001 > a = "hello"
=> "hello"
2.3.1 :002 > b = a
=> "hello"
2.3.1 :003 > b += " world"
=> "hello world"
2.3.1 :004 > a
=> "hello"
이 구별을 이해하는 것은 여러분이 루프를 다룰 때 많은 두통을 줄일 수 있습니다!
당신의 질문에 대한 직접적인 대답은 아니지만, 왜 완전히 뒤집힌 빈은 항상 제가 좋아하는 루비 기사 중 하나였을까요?또한 가비지 수집과 관련된 문자열에 대한 몇 가지 정보도 포함되어 있습니다.
언급URL : https://stackoverflow.com/questions/4684446/why-is-the-shovel-operator-preferred-over-plus-equals-when-building-a
'programing' 카테고리의 다른 글
다른 개발자들을 위한 프레임워크나 라이브러리를 구축하는 방법, 안전한 방법? (0) | 2023.06.03 |
---|---|
Eclipse에서 기본 텍스트 파일 인코딩을 변경하는 방법은 무엇입니까? (0) | 2023.06.03 |
VBA 복사 셀 값 및 형식 (0) | 2023.06.03 |
문자열을 null 가능한 int로 구문 분석하는 방법 (0) | 2023.06.03 |
텍스트 보기에서 텍스트를 가로 및 세로로 중앙에 배치하려면 어떻게 해야 합니까? (0) | 2023.06.03 |