使用Ruby,比较字符串的开头或结尾与子字符串的最快方法是什么?

3

字符串截取"Hello world!"[0, 5] == 'Hello'是 Ruby 中常用的习语,可以将一个字符串的前n个或最后n个字符与另一个字符串进行比较。正则表达式也可以实现这一功能。而且还有start_with?end_with?可以完成此操作。

对于速度最快,我应该使用哪个方法?

1个回答

4

考虑以下测试:

require 'fruity'

STR = '!' + ('a'..'z').to_a.join # => "!abcdefghijklmnopqrstuvwxyz"

以单个字符开头的字符串的结果:

compare do
  _slice { STR[0] == '!' }
  _start_with { STR.start_with?('!') }
  _regex { !!STR[/^!/] }
end

# >> Running each test 32768 times. Test will take about 1 second.
# >> _start_with is faster than _slice by 2x ± 1.0
# >> _slice is similar to _regex

多个字符作为字符串开头的结果:

compare do
  _slice { STR[0..4] == '!abcd' }
  _start_with { STR.start_with?('!abcd') }
  _regex { !!STR[/^!abcd/] }
end

# >> Running each test 32768 times. Test will take about 2 seconds.
# >> _start_with is faster than _slice by 2x ± 1.0
# >> _slice is similar to _regex

以单个字符结尾的字符串的结果:

compare do
  _slice { STR[-1] == 'z' }
  _end_with { STR.end_with?('z') }
  _regex { !!STR[/z$/] }
end

# >> Running each test 32768 times. Test will take about 2 seconds.
# >> _end_with is faster than _slice by 2x ± 1.0
# >> _slice is faster than _regex by 2x ± 1.0

多个字符结束字符串的结果:

compare do
  _slice { STR[-5..-1] == 'vwxyz' }
  _end_with { STR.end_with?('vwxyz') }
  _regex { !!STR[/vwxyz$/] }
end

# >> Running each test 16384 times. Test will take about 1 second.
# >> _end_with is faster than _slice by 2x ± 1.0
# >> _slice is similar to _regex

因此,为了清晰和快速,我们应该首选start_with?end_with?。如果需要使用模式,则切片或使用正则表达式是明显的选择。

基准测试这很有意义。我原本期望 start_with? 和 end_with? 能更快一些,因为它们可能不会构建任何字符串并将其返回给您,并且可以在字符串本身上执行比较。 - Mircea
start_with?end_with?之所以快速,是因为它们被编译并使用memcmp(),而不是解释执行并依赖于调用正则表达式引擎。换句话说,它们依赖于用于比较字符/字节的C函数,这些函数非常快速。 - the Tin Man
我相信我们是同意的 :) (即表达相同的意思) - Mircea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接