哪个更好:
x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x
x =~ /abc|def|ghi/
?
哪个更好:
x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x
x =~ /abc|def|ghi/
?
哪个更好?这个问题不能轻易回答,因为它们并不总是做同样的事情。
x == 'abc' || x == 'def' || x == 'ghi'
%w(abc def ghi).include? x
比较x
与固定字符串是否相等。 x
必须是这些值之一。在这两个选项中,我倾向于选择第二个,因为它更容易维护。想象一下,如果您必须比较二十、五十或一百个字符串会是什么样子。
第三个测试:
x ~= /abc|def|ghi/
匹配子字符串:
x = 'xyzghi'
(x =~ /abc|def|ghi/) # => 3
所以它与前两者不同。
编辑:在nash进行的基准测试中,有一些我会做出不同选择的地方。在MacBook Pro上使用Ruby 1.9.2-p180,这个测试运行了100万次循环,并比较了锚定正则表达式、使用分组以及每次循环时不拆分%w()
数组的结果:
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)
(?:...)
来避免捕获,并且还可以使用单词边界 /\b(?:abc|def|ghi)\b/
。否则,原始问题的提出者需要理解这种差异,否则在某些时候会有一些需要追踪的错误。 - the Tin Man/respond_to?/
,因为它使用了未转义的'?',所以它可以匹配"respond_to"或"respond_t"。在正则表达式中,'?'的意思是“匹配前面的字符零次或一次”。在这个特定的例子中,它很可能不会有严重的副作用,因为我们没有一个名为"respond_t"的方法来引起混淆,但是对于其他被匹配的字符串,它可能会导致代码逻辑上的严重泄漏。适当的模式应该是使用respond_to\?
,这将强制问号失去其“特殊性”并成为字面量。 - the Tin Man一些基准测试:
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)
所以你可以看到,第一种方法比其他方法更快。而且字符串越长,最后一种方法的速度就越慢:
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)
第一种方式可能会稍微快一些,因为它没有方法调用,而是直接进行字符串比较,但它也可能是最不易读和最难维护的。
第二种方式肯定是最酷的,也是使用Ruby的方式。它最易于维护,可能最容易阅读。
最后一种方式使用了老派的Perl正则表达式语法。速度相当快,维护起来不像第一种方式那么烦人,相当容易阅读。
我想这取决于你所说的“更好”是什么意思。