Check if there is a string variable in the rowset

Which one is better:

x == 'abc' || x == 'def' || x == 'ghi' %w(abc def ghi).include? x x =~ /abc|def|ghi/ 

?

+6
ruby
source share
3 answers

Which one is better? It is not easy to answer the question, because they do not all do the same thing.

 x == 'abc' || x == 'def' || x == 'ghi' %w(abc def ghi).include? x 

compare x with fixed rows for equality. x must be one of these values. Between the two, I tend to go with the second, because it is easier to maintain. Imagine what it would look like if you had to compare against twenty, fifty or hundreds of lines.

Third test:

 x ~= /abc|def|ghi/ 

matches substrings:

 x = 'xyzghi' (x =~ /abc|def|ghi/) # => 3 

so this is not the same as the first two.

EDIT: In the tests we did, there are some things that I would do differently. Using Ruby 1.9.2-p180 on a MacBook Pro, it checks 1,000,000 loops and compares the results of regular expression bindings using grouping, and also without breaking the %w() array every time through the loop:

 require 'benchmark' str = "test" n = 1_000_000 Benchmark.bm do |x| x.report { n.times { str == 'abc' || str == 'def' || str == 'ghi' } } x.report { n.times { %w(abc def ghi).include? str } } x.report { ary = %w(abc def ghi); n.times { ary.include? str } } x.report { n.times { str =~ /abc|def|ghi/ } } x.report { n.times { str =~ /^abc|def|ghi$/ } } x.report { n.times { str =~ /^(abc|def|ghi)$/ } } x.report { n.times { str =~ /^(?:abc|def|ghi)$/ } } x.report { n.times { str =~ /\b(?:abc|def|ghi)\b/ } } end # >> user system total real # >> 1.160000 0.000000 1.160000 ( 1.165331) # >> 1.920000 0.000000 1.920000 ( 1.920120) # >> 0.990000 0.000000 0.990000 ( 0.983921) # >> 1.070000 0.000000 1.070000 ( 1.068140) # >> 1.050000 0.010000 1.060000 ( 1.054852) # >> 1.060000 0.000000 1.060000 ( 1.063909) # >> 1.060000 0.000000 1.060000 ( 1.050813) # >> 1.050000 0.000000 1.050000 ( 1.056147) 
+7
source share

The first may be a little faster, since there are no method calls and your direct string comparisons, but its also probably the least readable and least supported one.

The second is by far the youngest, and a ruby ​​way to get around this. It is most convenient to maintain and is probably best read.

The latter method uses the old school regex syntax. Pretty fast, not as annoying as the first to support, readable enough.

I think it depends on what you mean by "better."

+2
source share

some guidelines:

 require 'benchmark' str = "test" Benchmark.bm do |x| x.report {100000.times {if str == 'abc' || str == 'def' || str == 'ghi'; end}} x.report {100000.times {if %w(abc def ghi).include? str; end}} x.report {100000.times {if str =~ /abc|def|ghi/; end}} end user system total real 0.250000 0.000000 0.250000 ( 0.251014) 0.374000 0.000000 0.374000 ( 0.402023) 0.265000 0.000000 0.265000 ( 0.259014) 

So, as you can see, the first method works faster than the other. And the longer the str, the slower the last way:

 str = "testasdasdasdasdasddkmfskjndfbdkjngdjgndksnfg" user system total real 0.234000 0.000000 0.234000 ( 0.248014) 0.405000 0.000000 0.405000 ( 0.403023) 1.046000 0.000000 1.046000 ( 1.038059) 
+2
source share

All Articles