首页 > 解决方案 > 如何正确测量正则表达式的性能?

问题描述

尝试一些正则表达式性能测试(听到一些谣言说 erlang 很慢)

>Fun = fun F(X) -> case X > 1000000 of true -> ok; false -> Y = X + 1, re:run(<<"1ab1jgjggghjgjgjhhhhhhhhhhhhhjgdfgfdgdfgdfgdfgdfgdfgdfgdfgdfgfgv">>, "^[a-zA-Z0-9_]+$"), F(Y) end end.
#Fun<erl_eval.30.128620087>
> timer:tc(Fun, [0]).                                                         
{17233982,ok}                                                                   
> timer:tc(Fun, [0]).   
{17155982,ok}

以及编译正则表达式后的一些测试

{ok, MP} = re:compile("^[a-zA-Z0-9_]+$").                                   
{ok,{re_pattern,0,0,0,                                                          
            <<69,82,67,80,107,0,0,0,16,0,0,0,1,0,0,0,255,255,255,
              255,255,255,...>>}}
> Fun = fun F(X) -> case X > 1000000 of true -> ok; false -> Y = X + 1, re:run(<<"1ab1jgjggghjgjgjhhhhhhhhhhhhhjgdfgfdgdfgdfgdfgdfgdfgdfgdfgdfgfgv">>, MP), F(Y) end end.               
#Fun<erl_eval.30.128620087>
> timer:tc(Fun, [0]).                                                         
{15796985,ok}                                                                   
>        
> timer:tc(Fun, [0]).
{15921984,ok}

http://erlang.org/doc/man/timer.html

除非另有说明,否则时间始终以毫秒为单位。

http://erlang.org/doc/man/re.html#compile-1

如果要在程序的生命周期内使用相同的表达式匹配多个主题,则在匹配之前编译正则表达式很有用。编译一次执行多次比每次想匹配都要编译效率高得多。

问题

  1. 为什么它向我返回微秒?(应该是毫秒?)
  2. 编译正则表达式没有太大区别,为什么?
  3. 我应该费心编译它吗?

标签: regexperformanceerlang

解决方案


  1. 在模块timer中,函数 tc/2 返回微秒
tc(Fun) -> {Time, Value}
tc(Fun, Arguments) -> {Time, Value}
tc(Module, Function, Arguments) -> {Time, Value}
    Types
    Module = module()
    Function = atom()
    Arguments = [term()]
    Time = integer()
      In microseconds
    Value = term()
  1. 因为在案例 1 中,函数Fun需要"^[a-zA-Z0-9_]+$"每次递归(100 万次)编译字符串。相比之下,在案例 2 中,您首先进行编译。然后将结果带入递归,所以这就是为什么性能是低于案例 1。

运行(主题,RE)-> {匹配,捕获} | 不匹配

主题 = iodata() | unicode:charlist()

RE = mp() | 数据()

正则表达式可以指定为 iodata() 在这种情况下它会自动编译(如 compile/2)并执行,或者指定为预编译的 mp() 在这种情况下它会直接针对主题执行。

  1. 是的,在将其引入递归之前,您应该注意先编译

推荐阅读