생각을 코드로 변환할 때 가장 익숙한 방법을 사용합니다. 이것들은 가장 먼저 떠오르는 방법이며 자동으로 찾아옵니다. 정리가 필요한 문자열이 표시되고 손가락으로 결과를 얻을 방법을 입력합니다.
종종 자동으로 입력하는 메소드는 가장 일반적인 Ruby 메소드입니다. #gsub
문자열의 문자를 대체하는 일반적인 방법입니다. 하지만 Ruby는 표준 작업을 위한 보다 전문화된 편리한 방법을 통해 훨씬 더 많은 것을 제공합니다.
저는 Ruby의 풍부한 관용구를 가장 좋아합니다. 왜냐하면 코드를 더 우아하고 읽기 쉽게 만들어주기 때문입니다. 이 풍부함의 이점을 누리려면 코드의 가장 간단한 부분(예:문자열 정리)을 리팩토링하는 데 시간을 할애해야 하며 어휘를 확장하는 데 약간의 노력이 필요합니다. 질문:추가 노력이 그만한 가치가 있습니까?
공백을 제거하는 4가지 방법
다음은 신용 카드 번호를 나타내는 문자열입니다:"055 444 285". 그것을 사용하기 위해 공백을 제거하고 싶습니다. #gsub
할 수 있다; #gsub
사용 모든 것을 대체할 수 있습니다. 하지만 다른 옵션이 있습니다.
string = "055 444 285"
string.gsub(/ /, '')
string.gsub(' ', '')
string.tr(' ', '')
string.delete(' ')
# => "055444285"
편의 방식에서 가장 마음에 드는 것은 표현력입니다. 마지막 것은 이에 대한 좋은 예입니다. "공백 삭제"보다 더 명확하지 않습니다. 옵션 간의 균형을 생각하면 성능 문제가 발생하지 않는 한 가독성이 최우선입니다. 그럼 제가 가장 좋아하는 솔루션인 #delete
정말 원인입니다.
위의 예를 벤치마킹했습니다. 이 방법 중 어느 것이 가장 빠를 것 같습니까?
Benchmark.ips do |x|
x.config(time: 30, warmup: 2)
x.report('gsub') { string.gsub(/ /, '') }
x.report('gsub, no regex') { string.gsub(' ', '') }
x.report('tr') { string.tr(' ','') }
x.report('delete') { string.delete(' ') }
x.compare!
end
성능이 가장 좋은 순서대로 추측합니다. 토글을 열어 결과 보기
Comparison:
delete: 2326817.5 i/s
tr: 2121629.8 i/s - 1.10x slower
gsub, no regex: 868184.1 i/s - 2.68x slower
gsub: 474970.5 i/s - 4.90x slower
자세히>
나는 순서에 대해 놀라지 않았지만 속도의 차이는 여전히 나를 놀라게했습니다. #gsub
느릴 뿐만 아니라 독자가 인수를 '디코딩'하는 데 추가 노력이 필요합니다. 단순한 공간 이상을 정리할 때 이 비교가 어떻게 작동하는지 봅시다.
번호 선택
다음 전화번호를 사용하세요. '(408) 974-2414'
. 숫자 => 4089742414
만 필요하다고 가정해 보겠습니다. . #scan
을 추가했습니다. 또한 원하지 않는 것을 모두 제거하려고 하기보다 특정한 것을 목표로 한다는 것을 더 명확하게 표현하는 것이 좋기 때문입니다.
Benchmark.ips do |x|
x.config(time: 30, warmup: 2)
x.report ('gsub') { string.gsub(/[^0-9] /, '') }
x.report('tr') { string.tr("^0-9", "") }
x.report('delete_chars') { string.delete("^0-9") }
x.report('scan') { string.scan(/[0-9]/).join }
x.compare!
end
다시, 순서를 추측한 다음 토글을 열어 답을 확인하세요.
Comparison:
delete_chars: 2006750.8 i/s
tr: 1856429.0 i/s - 1.08x slower
gsub: 523174.7 i/s - 3.84x slower
scan: 227717.4 i/s - 8.81x slower
자세히>
정규식을 사용하면 속도가 느려지는데, 이는 놀라운 일이 아닙니다. 그리고 #scan
의 표현력을 드러내는 의도 비용이 많이 듭니다. 하지만 Ruby의 전문화된 방법으로 정리를 처리하는 방법을 보고 더 많은 맛을 느꼈습니다.
돈으로
"€ "
하위 문자열을 제거하는 몇 가지 방법을 시도해 보겠습니다. "€ 300"
문자열에서 . 다음 솔루션 중 일부는 정확한 하위 문자열 "€ "
을 지정합니다. , 일부는 단순히 모든 통화 기호 또는 숫자가 아닌 모든 문자를 제거합니다.
Benchmark.ips do |x|
x.config(time: 30, warmup: 2)
x.report('delete specific chars') { string.delete("€ ") }
x.report('delete non-numericals') { string.delete("^0-9") }
x.report('delete prefix') { string.delete_prefix("€ ") }
x.report('delete prefix, strip') { string.delete_prefix("€").strip }
x.report('gsub') { string.gsub(/€ /, '') }
x.report('gsub-non-nums') { string.gsub(/[^0-9]/, '') }
x.report('tr') { string.tr("€ ", "") }
x.report('slice array') { string.chars.slice(2..-1).join }
x.report('split') { string.split.last }
x.report('scan nums') { string.scan(/\d/).join }
x.compare!
end
승자가 #delete
에스. 하지만 #delete
변형이 가장 빠를 것으로 예상하십니까? 플러스:다른 방법 중 하나가 일부 #delete
보다 빠릅니다. 에스. 어느 것입니까?
추측하고 엽니다.
Comparison:
delete prefix: 4236218.6 i/s
delete prefix, strip: 3116439.6 i/s - 1.36x slower
split: 2139602.2 i/s - 1.98x slower
delete non-numericals: 1949754.0 i/s - 2.17x slower
delete specific chars: 1045651.9 i/s - 4.05x slower
tr: 951352.0 i/s - 4.45x slower
slice array: 681196.2 i/s - 6.22x slower
gsub: 548588.3 i/s - 7.72x slower
gsub-non-nums: 489744.8 i/s - 8.65x slower
scan nums: 418978.8 i/s - 10.11x slower
자세히>
배열을 슬라이싱하는 것조차 #gsub
보다 빠르다는 사실에 놀랐습니다. #split
이다. 숫자가 아닌 모든 것을 삭제하는 것이 특정 부분 문자열을 삭제하는 것보다 빠릅니다.
돈을 따라라
숫자 뒤의 통화를 제거합시다. (저는 느린 #gsub
변형.)
Benchmark.ips do |x|
x.config(time: 30, warmup: 2)
x.report('gsub') { string.gsub(/ USD/, '')
x.report('tr') { string.tr(" USD", "") }
x.report('delete_chars') { string.delete("^0-9")
x.report('delete_suffix') { string.delete_suffix(" USD") }
x.report('to_i.to_s') { string.to_i.to_s }
x.report("split") { string.split.first }
x.compare!
end
승자간에 무승부가 있습니다. 가장 빠른 2인자가 되기 위해 경쟁할 것으로 예상되는 두 가지는 무엇입니까?
그리고:`#gsub`가 _얼마나_ 더 느린지 맞춰보세요. 요약> Comparison:
delete_suffix: 4354205.4 i/s
to_i.to_s: 4307614.6 i/s - same-ish: difference falls within error
split: 2870187.8 i/s - 1.52x slower
delete_chars: 1989566.1 i/s - 2.19x slower
tr: 1853957.1 i/s - 2.35x slower
gsub: 524080.6 i/s - 13.22x slower
자세히>
귀하의 요구에 맞는 특별한 방법이 항상 있는 것은 아닙니다. #to_i
를 사용할 수 없습니다. 선행 "0"을 유지해야 하는 경우. 그리고 #delete_suffix
통화가 미국 달러라는 가정에 크게 의존합니다.
특수화된 방법은 정밀 도구와 같으며 특정 컨텍스트의 특정 작업에 적합합니다. 따라서 #gsub
바로 우리에게 필요한 것입니다. 다재다능하며 항상 최우선으로 생각합니다. 그러나 처리하기가 조금 더 어려울 수 있으며 종종 예상보다 더 느립니다. 나에게 Ruby의 풍부함은 작업을 매우 즐겁게 만드는 이유 중 하나이기도 합니다. 속도 승리는 좋은 보너스입니다.
Comparison:
delete_suffix: 4354205.4 i/s
to_i.to_s: 4307614.6 i/s - same-ish: difference falls within error
split: 2870187.8 i/s - 1.52x slower
delete_chars: 1989566.1 i/s - 2.19x slower
tr: 1853957.1 i/s - 2.35x slower
gsub: 524080.6 i/s - 13.22x slower
#to_i
를 사용할 수 없습니다. 선행 "0"을 유지해야 하는 경우. 그리고 #delete_suffix
통화가 미국 달러라는 가정에 크게 의존합니다.#gsub
바로 우리에게 필요한 것입니다. 다재다능하며 항상 최우선으로 생각합니다. 그러나 처리하기가 조금 더 어려울 수 있으며 종종 예상보다 더 느립니다. 나에게 Ruby의 풍부함은 작업을 매우 즐겁게 만드는 이유 중 하나이기도 합니다. 속도 승리는 좋은 보너스입니다.