Skip to content

String#=~ faster than String#match - #59

Merged
JuanitoFatas merged 1 commit into
fastruby:masterfrom
schneems:schneems/string-equal-squigly
Aug 7, 2015
Merged

String#=~ faster than String#match#59
JuanitoFatas merged 1 commit into
fastruby:masterfrom
schneems:schneems/string-equal-squigly

Conversation

@schneems

Copy link
Copy Markdown
Contributor

If you're only looking for presence of a match and don't need the matchdata, use String#=~

schneems/rails@1bf50ba#commitcomment-12572839

If you're only looking for presence of a match and don't need the matchdata, use String#=~ schneems/rails@1bf50ba#commitcomment-12572839
schneems referenced this pull request in schneems/rails Aug 6, 2015
In `apply_inflections` a string is down cased and some whitespace stripped in the front (which allocate strings). This would normally be fine, however `uncountables` is a fairly small array (10 elements out of the box) and this method gets called a TON. Instead we can keep an array of valid regexes for each uncountable so we don't have to allocate new strings.
This change buys us 325,106 bytes of memory and 3,251 fewer objects per request.
@Arcovion

Copy link
Copy Markdown
Collaborator

Regexp#=== is a tiny bit faster on my machine, worth including:

require'benchmark/ips'deffastest/boo/ === 'foo'.freezeenddeffast'foo'.freeze =~ /boo/enddefslow'foo'.freeze.match(/boo/)endBenchmark.ipsdo |bm|
bm.report("Regexp#==="){fastest}bm.report("String#=~"){fast}bm.report("String#match"){slow}bm.compare!end
Calculating -------------------------------------
Regexp#=== 116.319k i/100ms
String#=~ 119.576k i/100ms
String#match 102.506k i/100ms
-------------------------------------------------
Regexp#=== 3.048M (± 1.5%) i/s - 15.238M
String#=~ 2.988M (± 1.4%) i/s - 14.947M
String#match 2.482M (± 1.2%) i/s - 12.506M
Comparison:
Regexp#===: 3047884.6 i/s
String#=~: 2988148.2 i/s - 1.02x slower
String#match: 2481615.6 i/s - 1.23x slower

@schneems

Copy link
Copy Markdown
ContributorAuthor

Yep

Calculating -------------------------------------
String#=~ 66.023k i/100ms
String#match 60.124k i/100ms
String#=== 70.747k i/100ms
-------------------------------------------------
String#=~ 1.798M (±10.3%) i/s - 8.913M
String#match 1.374M (± 9.7%) i/s - 6.854M
String#=== 1.847M (± 9.8%) i/s - 9.197M

Seems good. How should I report this? I would like to have all 3 examples in the code and reported.

@Arcovion

Copy link
Copy Markdown
Collaborator

Edited my comment as String#=== was wrong, I meant Regexp#===
Added example of how it might look...

@JuanitoFatas

Copy link
Copy Markdown
Contributor

How about list all possibilities (code/string/===-vs-=~-vs-match.rb)?

require"benchmark/ips"deffastest"foo".freeze === /boo/enddeffaster"foo".freeze =~ /boo/enddeffast/boo/ === "foo".freezeenddefslow"foo".freeze.match(/boo/)endBenchmark.ipsdo |x|
x.report("String#==="){fastest}x.report("Regexp#==="){faster}x.report("String#=~"){fast}x.report("String#match"){slow}x.compare!end
ruby -v code/string/match-vs-=\~.rb
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
Calculating -------------------------------------
String#=== 143.440k i/100ms
Regexp#=== 94.853k i/100ms
String#=~ 91.999k i/100ms
String#match 88.397k i/100ms
-------------------------------------------------
String#=== 5.637M (± 7.4%) i/s - 28.114M
Regexp#=== 2.599M (± 5.4%) i/s - 12.995M
String#=~ 2.318M (± 7.7%) i/s - 11.592M
String#match 1.905M (± 8.4%) i/s - 9.458M
Comparison:
String#===: 5637360.8 i/s
Regexp#===: 2599326.4 i/s - 2.17x slower
String#=~: 2318149.8 i/s - 2.43x slower
String#match: 1905484.8 i/s - 2.96x slower

@Arcovion

Copy link
Copy Markdown
Collaborator

String#=== doesn't work, it's not the correct result.

@JuanitoFatas

Copy link
Copy Markdown
Contributor

String#=== doesn't work, it's not the correct result.

Yup. The #59 (comment) is wrong.

Let's keep this simple since the regexp need to flip the string to be compared to the end. Which is counterintuitive

JuanitoFatas added a commit that referenced this pull request Aug 7, 2015
@JuanitoFatas
JuanitoFatas merged commit df633ee into fastruby:masterAug 7, 2015
schneems added a commit to schneems/rails that referenced this pull request Aug 7, 2015
@schneems

Copy link
Copy Markdown
ContributorAuthor

It's a pretty big speed boost, we would have to rename it to Regexp#=== and we could put a warning in about not switching the arguments cause you'll get the wrong results

JuanitoFatas added a commit that referenced this pull request Nov 4, 2015
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@schneems@Arcovion@JuanitoFatas