RegEx 性能:交替 vs Trie

对于Wolfram 语言的 Google Prettify 语法高亮,我需要将所有标识符与大约 7000 个内置函数名称的大列表进行匹配,以将它们高亮显示为关键字。过去,我只是使用了一个由许多交替组成的正则表达式。举一个具体的例子,这里是所有以 开头的函数Plot

(:?Plot|Plot3D|Plot3Matrix|PlotDivision|PlotJoined|PlotLabel|PlotLabels|PlotLayout|PlotLegends|PlotMarkers|PlotPoints|PlotRange|PlotRangeClipping|PlotRangeClipPlanesStyle|PlotRangePadding|PlotRegion|PlotStyle|PlotTheme)

从理论上讲,这是一个糟糕的选择,因为每个替代关键字都需要重复进行子匹配。人们可以做的是构建一个Trie(或前缀树)并从中构建一个正则表达式。如果前缀不正确,这将跳过所有子匹配。对于上面的单词,这看起来像这样

(:?Plot(?:3(?:D|Matrix)|Division|Joined|L(?:a(?:bel(?:s)?|yout)|egends)|Markers|Points|R(?:ange(?:Clip(?:PlanesStyle|ping)|Padding)?|egion)|Style|Theme)?)

虽然这看起来有点乱,但想法很简单:它测试前缀Plot,如果不匹配,则不需要进一步测试。如果匹配,则跳转到内部表达式并测试下一个前缀,直到它具有完全匹配或不匹配。

我已经为所有 7000 个与自身匹配的关键字和 7000 个字典单词的正则表达式计时,作为使用 Kotlin 的反例。Trie 实现需要 78 毫秒,而交替正则表达式需要 523 毫秒。这是我预期的巨大改进。

但是,在 JavaScript 中,Trie 实现似乎有点慢。出于分析的目的,我设置了 2 个网页,它们使用两种不同的方法调用美化引擎。是 Trie 实现,是交替实现。然后我使用 Chrome 开发工具对此进行了分析,但我对 JS 并不是特别有经验。

问题:

  1. 有人可以解释一下,为什么当 (a) 正则表达式本身更小(尽管嵌套严重)和 (b) 正则表达式匹配时理论上应该有很多捷径时,为什么 Trie 正则表达式看起来更慢?

  2. 鉴于这里这里的两个测试站点甚至纯正则表达式,有人能告诉我如何正确地描述它吗?关键字和字典词列表可在此处获得


鸿蒙传说
浏览 297回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript