いくつかのベンチマークが整っています。
Perry Horwich の答えは基本的に Huluk の答えと同じなので、同じ結果になると思いました。へー、私は間違っていた。それを見て、正規表現ではなく文字列検索を行っていることに気付いた後、それを修正し、固定テストを追加しました。
その後、何を思いつくことができるかを確認するために、いじくり回しました。私のソリューションは他のソリューションほど単純ではないようですが、最初のソリューションは短い文字列でも同じように高速に動作し、長い文字列ではおそらく少し速くなります。2 番目の 2 つは、短い文字列または長い文字列を処理する場合にはウォッシュですが、どちらも非常に高速です。私は昔ながらの手法に戻り、「昔」にアセンブラーで行っていた方法でそれらを実行しました。
require 'benchmark'
n = 1_000_000
def huluk(s)
s.sub %r{/+$}, ''
end
def apneadiving1(your_string)
matches = your_string.match(/(.*?)\/*$/)
matches[1]
end
def apneadiving2(your_string)
your_string.scan(/(.*?)\/*$/).flatten.first
end
def fixed_perry_horwich(my_beginning_string)
my_beginning_string.sub(/\/+$/,'')
end
def the_tin_man1(s)
s.split(%r[/+$]).first
end
def the_tin_man2(s)
s = s[0..-2] while s[-1] == '/'
s
end
def the_tin_man3(s)
s_len = s.length - 1
s_len -= 1 while s[s_len] == '/'
s[0..s_len]
end
puts "Ruby #{ RUBY_VERSION }"
puts "#{ n } iterations"
puts
[
'abc//',
'abc' * 50 + '//',
'abc' * 10 + '////',
'////////////'
].each do |sample_string|
puts "sample string: #{ sample_string }"
puts 'huluk: %s' % huluk(sample_string)
puts 'perry_horwich: %s' % perry_horwich(sample_string)
puts 'fixed_perry_horwich: %s' % fixed_perry_horwich(sample_string)
puts 'apneadiving1: %s' % apneadiving1(sample_string)
puts 'apneadiving2: %s' % apneadiving2(sample_string)
puts 'the_tin_man1: %s' % the_tin_man1(sample_string)
puts 'the_tin_man2: %s' % the_tin_man2(sample_string)
puts 'the_tin_man3: %s' % the_tin_man3(sample_string)
puts
Benchmark.bm(19) do |b|
2.times do
b.report('huluk') { n.times { huluk(sample_string) } }
b.report('fixed_perry_horwich') { n.times { fixed_perry_horwich(sample_string) } }
b.report('apneadiving1') { n.times { apneadiving1(sample_string) } }
b.report('apneadiving2') { n.times { apneadiving2(sample_string) } }
b.report('the_tin_man1') { n.times { the_tin_man1(sample_string) } }
b.report('the_tin_man2') { n.times { the_tin_man2(sample_string) } }
b.report('the_tin_man3') { n.times { the_tin_man3(sample_string) } }
puts
end
end
puts
end
結果:
ルビー1.9.3
1000000回の繰り返し
サンプル文字列: abc//
フルク: abc
ペリー・ホウィッチ: abc//
fixed_perry_horwich: abc
apneadiving1: abc
apneadiving2: abc
the_tin_man1: abc
the_tin_man2: abc
the_tin_man3: abc
ユーザーシステム合計実数
フルク 1.840000 0.000000 1.840000 ( 1.849929)
fixed_perry_horwich 1.840000 0.010000 1.850000 (1.847069)
apneadiving1 1.900000 0.010000 1.910000 ( 1.900817)
apneadiving2 4.860000 0.010000 4.870000 ( 4.883103)
the_tin_man1 1.830000 0.000000 1.830000 ( 1.826547)
the_tin_man2 1.150000 0.000000 1.150000 ( 1.151420)
the_tin_man3 1.170000 0.010000 1.180000 ( 1.168161)
フルク 1.820000 0.000000 1.820000 (1.825440)
fixed_perry_horwich 1.830000 0.000000 1.830000 ( 1.827306)
apneadiving1 1.850000 0.000000 1.850000 ( 1.853751)
apneadiving2 4.830000 0.000000 4.830000 ( 4.825394)
the_tin_man1 1.810000 0.000000 1.810000 ( 1.811503)
the_tin_man2 1.150000 0.000000 1.150000 ( 1.151865)
the_tin_man3 1.170000 0.000000 1.170000 ( 1.172259)
サンプル文字列: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc//
huluk: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
perry_horwich: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc//
fixed_perry_horwich: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
apneadiving1: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
apneadiving2: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man1: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man2: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man3: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
ユーザーシステム合計実数
フルク 2.120000 0.000000 2.120000 (2.122156)
fixed_perry_horwich 2.130000 0.010000 2.140000 (2.136665)
apneadiving1 9.630000 0.030000 9.660000 ( 9.656817)
apneadiving2 12.420000 0.030000 12.450000 ( 12.459432)
the_tin_man1 2.080000 0.010000 2.090000 ( 2.090112)
the_tin_man2 1.570000 0.010000 1.580000 ( 1.573887)
the_tin_man3 1.380000 0.000000 1.380000 ( 1.388120)
フルク 2.130000 0.010000 2.140000 (2.134414)
fixed_perry_horwich 2.120000 0.010000 2.130000 (2.129399)
apneadiving1 9.620000 0.020000 9.640000 ( 9.646624)
apneadiving2 12.410000 0.020000 12.430000 ( 12.423327)
the_tin_man1 2.080000 0.010000 2.090000 ( 2.090938)
the_tin_man2 1.580000 0.010000 1.590000 ( 1.581131)
the_tin_man3 1.390000 0.000000 1.390000 ( 1.400093)
サンプル文字列: abcabcabcabcabcabcabcabcabcabc////
huluk: abcabcabcabcabcabcabcabcabcabc
perry_horwich: abcabcabcabcabcabcabcabcabcabc////
fixed_perry_horwich: abcabcabcabcabcabcabcabcabcabc
apneadiving1: abcabcabcabcabcabcabcabcabcabc
apneadiving2: abcabcabcabcabcabcabcabcabcabc
the_tin_man1: abcabcabcabcabcabcabcabcabcabc
the_tin_man2: abcabcabcabcabcabcabcabcabcabc
the_tin_man3: abcabcabcabcabcabcabcabcabcabc
ユーザーシステム合計実数
フルク 1.980000 0.010000 1.990000 (1.983149)
fixed_perry_horwich 1.970000 0.010000 1.980000 ( 1.979796)
apneadiving1 3.500000 0.010000 3.510000 ( 3.513885)
apneadiving2 6.320000 0.020000 6.340000 ( 6.348327)
the_tin_man1 2.070000 0.010000 2.080000 ( 2.075045)
the_tin_man2 2.800000 0.000000 2.800000 ( 2.801136)
the_tin_man3 1.840000 0.010000 1.850000 ( 1.851506)
フルク 1.980000 0.010000 1.990000 (1.980867)
fixed_perry_horwich 1.980000 0.010000 1.990000 (1.984776)
apneadiving1 3.510000 0.010000 3.520000 ( 3.523383)
apneadiving2 6.340000 0.020000 6.360000 ( 6.357442)
the_tin_man1 2.070000 0.000000 2.070000 ( 2.074559)
the_tin_man2 2.800000 0.010000 2.810000 ( 2.814275)
the_tin_man3 1.850000 0.010000 1.860000 ( 1.855621)
サンプル文字列: ////////////
フルク:
ペリー・ホウィッチ: ////////////
fixed_perry_horwich:
アプネダイビング1:
アプネダイビング2:
the_tin_man1:
the_tin_man2:
the_tin_man3:
ユーザーシステム合計実数
フルク 1.980000 0.010000 1.990000 (1.982700)
fixed_perry_horwich 1.980000 0.010000 1.990000 (1.984354)
apneadiving1 1.860000 0.000000 1.860000 ( 1.869155)
apneadiving2 4.840000 0.020000 4.860000 ( 4.852445)
the_tin_man1 2.010000 0.000000 2.010000 ( 2.020292)
the_tin_man2 5.060000 0.020000 5.080000 ( 5.070202)
the_tin_man3 6.390000 0.020000 6.410000 ( 6.412697)
フルク 1.980000 0.010000 1.990000 (1.987652)
fixed_perry_horwich 1.980000 0.010000 1.990000 ( 1.981360)
apneadiving1 1.860000 0.000000 1.860000 ( 1.871577)
apneadiving2 4.850000 0.020000 4.870000 ( 4.857329)
the_tin_man1 2.010000 0.010000 2.020000 ( 2.023877)
the_tin_man2 5.060000 0.010000 5.070000 ( 5.067753)
the_tin_man3 6.410000 0.020000 6.430000 ( 6.434523)
提示されたパターンとアルゴリズムに敵対するために、単純なケースと"abc//"
、152 文字の「悪いケース」と見なすものを区別しようとしました。
huluk
ソースがRubyによって解釈されるとfixed_perry_horwich
、それらの違いがコンパイルされてしまうためです。
編集:
いくつかの変更:
- コードをリファクタリングして DRY にしました。
perry_horwich
テストする意味がなかったので、ベンチマークからテストを削除しました。
'////////////'
@pguardiario の推奨でテストを追加しました。これは、区切り文字を取り除いた最悪のケースのテストの結果を示しています。
テスト結果から得られるのは、テストされるデータの種類を見て、入力に最適なアルゴリズムを選択することです。一部の入力でうまく機能するものが、他の入力でもうまく機能するとは限りません。「昔ながらの」方法が、短い末尾区切り文字列に正規表現を使用するソリューションよりも優れていることは興味深いことでした。これは、Ruby がコンパイル済みコードへの呼び出しを設定した結果だと思います。区切り文字列が長くなると、コンパイルされたコードが有利になります。