进行此测试的最有效技术是使用string match 或regexp。您还可以使用 string last 或 string range 并测试其是否相等。
让我们测试一下!
设置
% set str "name.{j}.name.{i}.param"
name.{j}.name.{i}.param
% set pat "{i}.param"
{i}.param
使用string match
% string match *$pat $str
1
% time {string match *$pat $str} 10000
8.0875808 microseconds per iteration
通过移除时序循环之外的模式构造进行优化:
% set glob *$pat
*{i}.param
% time {string match $glob $str} 10000
5.4690824000000005 microseconds per iteration
使用string last
% expr {[string last $pat $str]==[string length $str]-[string length $pat]}
1
% time {expr {[string last $pat $str] == [string length $str]-[string length $pat]}} 10000
10.675282300000001 microseconds per iteration
好的,这出奇的慢。让我们尝试分解一些计算:
% set len [expr {[string length $str] - [string length $pat]}]
14
% time {expr {[string last $pat $str] == $len}} 10000
6.8803367 microseconds per iteration
% time {expr {[string last $pat $str] == 14}} 10000
6.835114999999999 microseconds per iteration
更快,但不如string match。如果模式不存在,则在长输入字符串上速度较慢。
使用string range
% time {expr {[string range $str end-[expr {[string length $pat]-1}] end] eq $pat}} 10000
11.9834488 microseconds per iteration
通过分解静态计算再次优化:
% set idx end-[expr {[string length $pat]-1}]
end-8
% time {expr {[string range $str $idx end] eq $pat}} 10000
7.7081886 microseconds per iteration
% time {expr {[string range $str end-8 end] eq $pat}} 10000
7.261692600000001 microseconds per iteration
这又回到了球场上,并且将具有一致的性能。
使用regexp
请注意,我们需要做一些工作来准备正则表达式,因为它包含元字符,但我们想要进行末端锚定匹配。这个准备步骤本身就很昂贵。
% time {regexp [regsub -all {\W} $pat {\\&}]$ $str} 10000
24.428607500000002 microseconds per iteration
哦!你! C!啊!
让我们考虑一下 RE 的构建和重定时:
% set RE [regsub -all {\W} $pat {\\&}]$
\{i\}\.param$
% regexp $RE $str
1
% time {regexp $RE $str} 10000
5.4204058 microseconds per iteration
快。但我们需要提前完成构建步骤。
总结
虽然使用regexp 速度很快,但实际上使用起来很棘手,因为准备步骤本身就很昂贵。我建议在正常使用中使用string match 方法。