regex - 如何正确测量正则表达式的性能?
问题描述
尝试一些正则表达式性能测试(听到一些谣言说 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:
如果要在程序的生命周期内使用相同的表达式匹配多个主题,则在匹配之前编译正则表达式很有用。编译一次执行多次比每次想匹配都要编译效率高得多。
问题
- 为什么它向我返回微秒?(应该是毫秒?)
- 编译正则表达式没有太大区别,为什么?
- 我应该费心编译它吗?
解决方案
- 在模块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 中,函数
Fun
需要"^[a-zA-Z0-9_]+$"
每次递归(100 万次)编译字符串。相比之下,在案例 2 中,您首先进行编译。然后将结果带入递归,所以这就是为什么性能是低于案例 1。
运行(主题,RE)-> {匹配,捕获} | 不匹配
主题 = iodata() | unicode:charlist()
RE = mp() | 数据()
正则表达式可以指定为 iodata() 在这种情况下它会自动编译(如 compile/2)并执行,或者指定为预编译的 mp() 在这种情况下它会直接针对主题执行。
- 是的,在将其引入递归之前,您应该注意先编译
推荐阅读
- mysql - 如何比较mysql中2个表中的值
- coldfusion - CFMail 附件文件名在 Windows 服务器上的 ColdFusion 2016 中损坏
- ios - 日志文件(崩溃信息) - iOS 应用程序 (Swift)
- ios - iOS Firebase Crashlytics 缺少 dSYM
- php - 带有 F 选项的 PHP FPDF 输出
- asp.net - 如何在 asp.net 核心中使用 ajax 将表行数据发布到控制器
- bitbucket - 如何将现有 bitbucket 存储库中的所有代码复制到 bitbucket 中的新存储库
- actionscript-3 - 使用 AS3 创建语音识别游戏?
- mysql - Node.js MySQL 查询的结果
- php - php 基于周的日历月初