【发布时间】:2015-10-06 18:10:57
【问题描述】:
对字符串进行切片"Hello world!"[0, 5] == 'Hello' 是Ruby 中的一个常用习惯用法,用于将字符串的第一个或最后n 个字符与另一个字符串进行比较。正则表达式也可以做到。还有start_with? 和end_with? 也可以做到这一点。
我应该使用哪个速度最快?
【问题讨论】:
对字符串进行切片"Hello world!"[0, 5] == 'Hello' 是Ruby 中的一个常用习惯用法,用于将字符串的第一个或最后n 个字符与另一个字符串进行比较。正则表达式也可以做到。还有start_with? 和end_with? 也可以做到这一点。
我应该使用哪个速度最快?
【问题讨论】:
考虑这些测试:
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? 快速的原因是因为它们已编译并使用memcmp(),而不是解释并且不依赖于调用正则表达式引擎。换句话说,它们依赖于用于比较字符/字节的 C 函数,这非常快。