为什么这个正则表达式调用substcont的次数过多?
这比其他任何事都更好奇,因为我没有在Google上找到关于这个函数的任何有用信息(CORE :: substcont)
在分析和优化一些陈旧,缓慢的XML解析代码时,我发现以下正则表达式每次执行该行时都会调用substcont 31次,并占用大量时间:
电话:10000时间:2.65秒子电话:320000时间:1.15秒
  $handle =~s/(>)s*(<)/$1n$2/g;
  # spent  1.09s making 310000 calls to main::CORE:substcont, avg 4µs/call
  # spent  58.8ms making  10000 calls to main::CORE:subst, avg 6µs/call
与前一行相比:
电话:10000时间:371毫秒子电话:30000时间在小数:221毫秒
  $handle =~s/(.*)s*(<?)/$1n$2/g;
    # spent   136ms making 10000 calls to main::CORE:subst, avg 14µs/call
    # spent  84.6ms making 20000 calls to main::CORE:substcont, avg 4µs/call
substcont调用的数量非常令人惊讶,尤其是看到我认为第二个正则表达式会更加昂贵。 显然,这是为什么剖析是一件好事;-)
随后,我改变了这两行以删除不必要的backrefs,对于行为不良的行显着提高了结果:
电话:10000时间:393毫秒子电话:10000时间在小数:341毫秒
$handle =~s/>s*</>n</g;
  # spent   341ms making 10000 calls to main::CORE:subst, avg 34µs/call
  substcont是Perl的替代迭代器的内部名称。  与s/// 。  根据我所掌握的信息,似乎在执行substcont会触发substcont。  也就是说,当$1存在时。  你可以用B :: Concise稍微玩一下。 
这里是没有backref的简单正则表达式的操作码。
$ perl -MO=Concise,-exec -we'$foo = "foo";  $foo =~ s/(foo)/bar/ig'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "foo"] s
4  <#> gvsv[*foo] s
5  <2> sassign vKS/2
6  <;> nextstate(main 1 -e:1) v:{
7  <#> gvsv[*foo] s
8  <$> const[PV "bar"] s
9  </> subst(/"(foo)"/) vKS
a  <@> leave[1 ref] vKP/REFC
-e syntax OK
和一个。
$ perl -MO=Concise,-exec -we'$foo = "foo";  $foo =~ s/(foo)/$1/ig'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "foo"] s
4  <#> gvsv[*foo] s
5  <2> sassign vKS/2
6  <;> nextstate(main 1 -e:1) v:{
7  <#> gvsv[*foo] s
8  </> subst(/"(foo)"/ replstart->9) vKS
9      <#> gvsv[*1] s
a      <|> substcont(other->8) sK/1
b  <@> leave[1 ref] vKP/REFC
-e syntax OK
这就是我所能提供的。 您可能想尝试Rx,mjd的旧正则表达式调试器。
链接地址: http://www.djcxy.com/p/45907.html上一篇: Why was this regex calling substcont an excessive number of times?
