Skip to content

Commit 9907db5

Browse files
committed
Add faster String#match? to Regexp#=== vs String#match vs String#=~ comparison
I did not change the filename of the test for clarity's sake. Also the question mark is a reserved character on Windows.
1 parent 1b90498 commit 9907db5

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,32 +1037,35 @@ Comparison:
10371037
String#[0...n] ==: 427206.8 i/s - 4.79x slower
10381038
```
10391039

1040-
##### `Regexp#===` vs `String#match` vs `String#=~` [code ](code/string/===-vs-=~-vs-match.rb)
1040+
##### `Regexp#===` vs `String#match` vs `String#=~` vs `String#match?` [code ](code/string/===-vs-=~-vs-match.rb)
1041+
1042+
`String#match?` and `Regexp#match?` are available on Ruby 2.4 or later.
1043+
ActiveSupport [provides](http://guides.rubyonrails.org/v5.1/active_support_core_extensions.html#match-questionmark)
1044+
a forward compatible extension of `Regexp` for older Rubies without the speed
1045+
improvement.
10411046

10421047
> :warning: <br>
1043-
> Sometimes you can't replace `match` with `=~`, <br>
1048+
> Sometimes you can't replace `match` with `match?`, <br>
10441049
> This is only useful for cases where you are checking <br>
10451050
> for a match and not using the resultant match object. <br>
10461051
> :warning: <br>
10471052
> `Regexp#===` is also faster than `String#match` but you need to switch the order of arguments.
10481053
10491054
```
1050-
$ ruby -v code/string/===-vs-=~-vs-match.rb.rb
1051-
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
1055+
$ ruby -v code/string/===-vs-=~-vs-match.rb
1056+
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-darwin17]
10521057
10531058
Calculating -------------------------------------
1054-
String#=~ 98.184k i/100ms
1055-
Regexp#=== 92.382k i/100ms
1056-
String#match 83.601k i/100ms
1057-
-------------------------------------------------
1058-
String#=~ 2.442M (± 7.6%) i/s - 12.175M
1059-
Regexp#=== 2.259M (± 7.9%) i/s - 11.271M
1060-
String#match 1.840M (± 7.3%) i/s - 9.196M
1059+
String#match? 6.284M (± 5.6%) i/s - 31.324M in 5.001471s
1060+
String#=~ 2.581M (± 4.7%) i/s - 12.977M in 5.038887s
1061+
Regexp#=== 2.482M (± 4.1%) i/s - 12.397M in 5.002808s
1062+
String#match 2.097M (± 4.3%) i/s - 10.592M in 5.060535s
10611063
10621064
Comparison:
1063-
String#=~: 2442335.1 i/s
1064-
Regexp#===: 2259277.3 i/s - 1.08x slower
1065-
String#match: 1839815.4 i/s - 1.33x slower
1065+
String#match?: 6283591.8 i/s
1066+
String#=~: 2581356.8 i/s - 2.43x slower
1067+
Regexp#===: 2482379.7 i/s - 2.53x slower
1068+
String#match: 2096984.3 i/s - 3.00x slower
10661069
```
10671070

10681071
See [#59](https://github.com/JuanitoFatas/fast-ruby/pull/59) and [#62](https://github.com/JuanitoFatas/fast-ruby/pull/62) for discussions.

code/string/===-vs-=~-vs-match.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
require "benchmark/ips"
22

3-
def fastest
3+
def fast
4+
"foo".freeze.match?(/boo/)
5+
end
6+
7+
def slow
48
"foo".freeze =~ /boo/
59
end
610

7-
def fast
11+
def slower
812
/boo/ === "foo".freeze
913
end
1014

11-
def slow
15+
def slowest
1216
"foo".freeze.match(/boo/)
1317
end
1418

1519
Benchmark.ips do |x|
16-
x.report("String#=~") { fastest }
17-
x.report("Regexp#===") { fast }
18-
x.report("String#match") { slow }
20+
x.report("String#match?") { fast } if RUBY_VERSION >= "2.4.0".freeze
21+
x.report("String#=~") { slow }
22+
x.report("Regexp#===") { slower }
23+
x.report("String#match") { slowest }
1924
x.compare!
2025
end

0 commit comments

Comments
 (0)