예:
[12,23,987,43
첫 번째 문자를 [
사용하여 " " 를 제거하는 가장 빠르고 효율적인 방법은 무엇입니까 chop()
?
delete_prefix
\ delete_prefix!
)을 벤치마킹했으며 매우 빠릅니다. 이전 즐겨 찾기 속도를 높이는 것은 아니지만 가독성은 새로운 옵션이 있다는 것을 의미합니다!
예:
[12,23,987,43
첫 번째 문자를 [
사용하여 " " 를 제거하는 가장 빠르고 효율적인 방법은 무엇입니까 chop()
?
delete_prefix
\ delete_prefix!
)을 벤치마킹했으며 매우 빠릅니다. 이전 즐겨 찾기 속도를 높이는 것은 아니지만 가독성은 새로운 옵션이 있다는 것을 의미합니다!
답변:
다음과 같은 것을 사용하는 것이 좋습니다.
asdf = "[12,23,987,43" asdf [0] = '' p asdf # >> "12,23,987,43"
나는 항상 가장 빠르고 읽기 쉬운 방법을 찾고 있습니다.
require 'benchmark'
N = 1_000_000
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
end
내 Mac Pro에서 실행 중 :
1.9.3
user system total real
[0] 0.840000 0.000000 0.840000 ( 0.847496)
sub 1.960000 0.010000 1.970000 ( 1.962767)
gsub 4.350000 0.020000 4.370000 ( 4.372801)
[1..-1] 0.710000 0.000000 0.710000 ( 0.713366)
slice 1.020000 0.000000 1.020000 ( 1.020336)
length 1.160000 0.000000 1.160000 ( 1.157882)
하나 더 제안 된 답변을 통합하기 위해 업데이트 :
require 'benchmark'
N = 1_000_000
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
b.report('eat!') { N.times { "[12,23,987,43".eat! } }
b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
결과 :
2.1.2
user system total real
[0] 0.300000 0.000000 0.300000 ( 0.295054)
sub 0.630000 0.000000 0.630000 ( 0.631870)
gsub 2.090000 0.000000 2.090000 ( 2.094368)
[1..-1] 0.230000 0.010000 0.240000 ( 0.232846)
slice 0.320000 0.000000 0.320000 ( 0.320714)
length 0.340000 0.000000 0.340000 ( 0.341918)
eat! 0.460000 0.000000 0.460000 ( 0.452724)
reverse 0.400000 0.000000 0.400000 ( 0.399465)
그리고 다른 /^./
첫 번째 문자를 찾는 데 사용 합니다.
require 'benchmark'
N = 1_000_000
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('[/^./]') { N.times { "[12,23,987,43"[/^./] = '' } }
b.report('[/^\[/]') { N.times { "[12,23,987,43"[/^\[/] = '' } }
b.report('sub+') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
b.report('eat!') { N.times { "[12,23,987,43".eat! } }
b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
결과 :
# >> 2.1.5
# >> user system total real
# >> [0] 0.270000 0.000000 0.270000 ( 0.270165)
# >> [/^./] 0.430000 0.000000 0.430000 ( 0.432417)
# >> [/^\[/] 0.460000 0.000000 0.460000 ( 0.458221)
# >> sub+ 0.590000 0.000000 0.590000 ( 0.590284)
# >> sub 0.590000 0.000000 0.590000 ( 0.596366)
# >> gsub 1.880000 0.010000 1.890000 ( 1.885892)
# >> [1..-1] 0.230000 0.000000 0.230000 ( 0.223045)
# >> slice 0.300000 0.000000 0.300000 ( 0.299175)
# >> length 0.320000 0.000000 0.320000 ( 0.325841)
# >> eat! 0.410000 0.000000 0.410000 ( 0.409306)
# >> reverse 0.390000 0.000000 0.390000 ( 0.393044)
더 빠른 하드웨어와 최신 버전의 Ruby에 대한 또 다른 업데이트가 있습니다.
2.3.1
user system total real
[0] 0.200000 0.000000 0.200000 ( 0.204307)
[/^./] 0.390000 0.000000 0.390000 ( 0.387527)
[/^\[/] 0.360000 0.000000 0.360000 ( 0.360400)
sub+ 0.490000 0.000000 0.490000 ( 0.492083)
sub 0.480000 0.000000 0.480000 ( 0.487862)
gsub 1.990000 0.000000 1.990000 ( 1.988716)
[1..-1] 0.180000 0.000000 0.180000 ( 0.181673)
slice 0.260000 0.000000 0.260000 ( 0.266371)
length 0.270000 0.000000 0.270000 ( 0.267651)
eat! 0.400000 0.010000 0.410000 ( 0.398093)
reverse 0.340000 0.000000 0.340000 ( 0.344077)
왜 gsub가 그렇게 느린가요?
검색 / 바꾸기를 한 후에 gsub
는 추가 일치 항목이 있는지 확인한 후 완료 여부를 알려야합니다. sub
하나만하고 마무리합니다. gsub
최소 두 번의 sub
통화 인 것을 고려하십시오 .
또한, 그 기억하는 것이 중요 gsub
하고, sub
또한 하위 문자열 검색보다 훨씬 더 느리게 일치 잘못 작성된 정규식에 의해 장애인 수 있습니다. 가능한 경우 정규 표현식을 고정하여 가장 빠른 속도를 얻으십시오. 여기에 스택 오버플로에 대한 답변이 있으므로 추가 정보를 원하면 검색하십시오.
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? "[12,23,987,43".shift NoMethodError: undefined method
"[12,23,987,43": String` 에 대한 shift '는 어떻습니까?
위의 Pablo의 대답과 비슷하지만 그늘 청소기 :
str[1..-1]
배열을 1에서 마지막 문자로 반환합니다.
'Hello World'[1..-1]
=> "ello World"
str[1,]
위와 비교 하여 성능은 어떻습니까?
str[1,]
범위가이므로 두 번째 문자를 반환합니다 1:nil
. str[1,999999]
전체 꼬리를 얻으려면 실제 계산 길이 또는 길이보다 더 높은 것이 보장되어야합니다 (물론 int_max 사용). [1..-1]
수동으로 길이를 조작 할 필요가 없기 때문에 더 깨끗하고 더 빠를 수 있습니다 (벤치 마크의 [1..length] 참조)
str[1..-2]
슬라이스를 사용하여이를 수행 할 수 있습니다.
val = "abc"
=> "abc"
val.slice!(0)
=> "a"
val
=> "bc"
사용하여 slice!
색인을 지정하여 모든 문자를 삭제할 수 있습니다.
slice!(0)
사용 asdf[0] = ''
하는 것이 어리석기 때문에 (정규식에서 gsub를 사용하고 곡사포로 비행하는 것처럼) 이 우아한 것은 실제로 선택된 대답이어야합니다 .
[]=
이 slice!
필요한 기본 C 코드를 많이 필요로하지 않습니다 . 추가됩니다. 논쟁은 "어느 것이 더 읽기 쉬운가?" 나는 []=
읽을 수있는 것을 사용 하지만 C-> Perl 배경에서 왔을 것입니다. 자바 개발자들은 아마도 읽기가 어렵다고 생각할 것입니다. 쉽게 이해하고 유지 관리 할 수 있고 CPU를 부적절하게로드하지 않는 한 작업을 수행 할 수있는 적절한 방법입니다.
Ruby 2.5부터는 읽을 수있는 방식으로이를 사용 delete_prefix
하거나 delete_prefix!
달성 할 수 있습니다 .
이 경우 "[12,23,987,43".delete_prefix("[")
.
여기에 더 많은 정보가 있습니다 :
'invisible'.delete_prefix('in') #=> "visible"
'pink'.delete_prefix('in') #=> "pink"
NB 당신도있는 문자열의 끝에서 항목을 제거하려면이 옵션을 사용할 수 있습니다 delete_suffix
및delete_suffix!
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
편집하다:
Tin Man의 벤치 마크 설정을 사용하면 (마지막 두 항목 아래 delete_p
및 delete_p!
) 매우 빠릅니다 . 하지 않습니다 매우 하지만, 속도에 대한 이전의 제품 구입에 PIP 매우 읽을 수 있습니다.
2.5.0
user system total real
[0] 0.174766 0.000489 0.175255 ( 0.180207)
[/^./] 0.318038 0.000510 0.318548 ( 0.323679)
[/^\[/] 0.372645 0.001134 0.373779 ( 0.379029)
sub+ 0.460295 0.001510 0.461805 ( 0.467279)
sub 0.498351 0.001534 0.499885 ( 0.505729)
gsub 1.669837 0.005141 1.674978 ( 1.682853)
[1..-1] 0.199840 0.000976 0.200816 ( 0.205889)
slice 0.279661 0.000859 0.280520 ( 0.285661)
length 0.268362 0.000310 0.268672 ( 0.273829)
eat! 0.341715 0.000524 0.342239 ( 0.347097)
reverse 0.335301 0.000588 0.335889 ( 0.340965)
delete_p 0.222297 0.000832 0.223129 ( 0.228455)
delete_p! 0.225798 0.000747 0.226545 ( 0.231745)
나는 이것을 선호한다 :
str = "[12,23,987,43"
puts str[1..-1]
>> 12,23,987,43
항상 선행 대괄호를 제거하려는 경우 :
"[12,23,987,43".gsub(/^\[/, "")
첫 번째 문자 만 제거하고 멀티 바이트 문자 집합이 아닌 경우 :
"[12,23,987,43"[1..-1]
또는
"[12,23,987,43".slice(1..-1)
"[12,23,987,43".sub(/^\[+/, "")
대신에 사용하고 싶습니다 gsub(/^\[/, "")
. 첫 번째는 정규식 엔진이 모든 일치 항목을 찾은 다음 한 번의 작업으로 교체되어 Ruby 1.9.3과 비교하여 속도가 약 2 배 향상됩니다.
gsub(/\A\[/, "")
합니까?
예를 들어 : a = "One Two Three"
1.9.2-p290 > a = "One Two Three"
=> "One Two Three"
1.9.2-p290 > a = a[1..-1]
=> "ne Two Three"
1.9.2-p290 > a = a[1..-1]
=> "e Two Three"
1.9.2-p290 > a = a[1..-1]
=> " Two Three"
1.9.2-p290 > a = a[1..-1]
=> "Two Three"
1.9.2-p290 > a = a[1..-1]
=> "wo Three"
이런 식으로 문자열의 첫 문자를 하나씩 제거 할 수 있습니다.
쉬운 방법:
str = "[12,23,987,43"
removed = str[1..str.length]
멋진 방법 :
class String
def reverse_chop()
self[1..self.length]
end
end
"[12,23,987,43".reverse_chop()
(참고 : 쉬운 방법을 선호하십시오 :))
"[12,23,987,43".reverse.chop.reverse
벤치 마크를 구성한 @ the-tin-man에게 감사합니다!
아아, 나는 그 해결책을 정말로 좋아하지 않는다. 결과를 얻는 데 추가 단계가 필요 하거나 ( [0] = ''
, .strip!
) 또는 무슨 일이 일어나고 있는지에 대한 의미가 명확하지 않거나 ( [1..-1]
"음, 1에서 음수 1? Yearg?") 느리거나 길다 ( .gsub
, .length
)를 쓰십시오 .
우리가 시도하는 것은 'shift'(배열 어휘)이지만 전환 된 것이 아니라 나머지 문자를 반환합니다. 우리의 루비를 사용하여 이것을 문자열로 가능하게합시다! 빠른 괄호 연산을 사용할 수 있지만 좋은 이름을 지정하고 앞면에서 얼마나 많은 부분을 쪼개고 싶은지를 지정합니다.
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
그러나 신속하지만 다루기 힘든 브래킷 조작으로 더 많은 일을 할 수 있습니다. 우리가 그것을 완성하는 동안 완전성을 위해 #shift
and를 #first
위해 (어레이는 왜 모든 재미를 가져야 하는가?), 우리가 처음부터 제거 할 문자 수를 지정하기 위해 arg를 작성합시다 :
class String
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
자, 이제 우리는과 일치하는 방법으로, 문자열의 앞에 떨어져 문자를 당기는 좋은 명확한 방법이 Array#first
와 Array#shift
(이 정말 ?? 쾅 방법이어야한다)를. 그리고 우리는 쉽게 수정 된 문자열을 얻을 수 있습니다 #eat!
. 흠, 우리는 새로운 eat!
ing 힘을 Array와 공유해야 합니까? 왜 안돼!
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
이제 우리는 할 수 있습니다 :
> str = "[12,23,987,43" #=> "[12,23,987,43"
> str.eat! #=> "12,23,987,43"
> str #=> "12,23,987,43"
> str.eat!(3) #=> "23,987,43"
> str #=> "23,987,43"
> str.first(2) #=> "23"
> str #=> "23,987,43"
> str.shift!(3) #=> "23,"
> str #=> "987,43"
> arr = [1,2,3,4,5] #=> [1, 2, 3, 4, 5]
> arr.eat! #=> [2, 3, 4, 5]
> arr #=> [2, 3, 4, 5]
그게 낫다!
chip()
대신에 chop()
(와 chimp()
의 아날로그 등 chomp()
)을.
str = "[12,23,987,43"
str[0] = ""