ANTLR4 性能的起点
Starting point for ANTLR4 performance
我已经迁移了一个相当大的 ANTLR2 grammar to ANTLR4,并且达到了两个语法的输出几乎相同的步骤,除了一些边缘情况。但是,有些文件的解析时间非常长(即使使用 SLL 预测模式和 BailOutStrategy),所以我想知道如何找到应该首先修复的规则。
我已经使用 Parser#setProfile() 收集了一些统计数据,但我不知道如何解释每个 DecisionInfo 对象中的结果。有没有关于如何开始优化大型 ANTLR4 语法并找到先追哪只兔子的好文档?
由于我不知道要在 DecisionInfo 对象中寻找什么,下面是我找到的内容,它帮助我将解析时间缩短了至少一个数量级。
首先,我使用 org.antlr.v4.runtime.Parser.setProfile(boolean profile)
启用语法分析,然后使用 org.antlr.v4.runtime.Parser.getInterpreter().setPredictionMode(PredictionMode.SLL)
对数千个文件执行解析器,并浏览预测时间最长的规则:
Arrays.stream(parser.getParseInfo().getDecisionInfo())
.filter(decision -> decision.timeInPrediction > 100000000)
.sorted((d1, d2) -> Long.compare(d2.timeInPrediction, d1.timeInPrediction))
.forEach(decision -> System.out.println(
String.format("Time: %d in %d calls - LL_Lookaheads: %d Max k: %d Ambiguities: %d Errors: %d Rule: %s",
decision.timeInPrediction / 1000000,
decision.invocations, decision.SLL_TotalLook,
decision.SLL_MaxLook, decision.ambiguities.size(),
decision.errors.size(), Proparse.ruleNames[Proparse._ATN.getDecisionState(decision.decision).ruleIndex])))
然后使用相同的 lamba 进行最高最大前瞻,除了:
filter(decision -> decision.SLL_MaxLook > 50).sorted((d1, d2) -> Long.compare(d2.SLL_MaxLook, d1.SLL_MaxLook))
这给了我 4 条规则,其中大部分时间都花在了上面,在这种情况下,这足以看到必须更改的内容(通过知道在哪里寻找问题)。
我已经迁移了一个相当大的 ANTLR2 grammar to ANTLR4,并且达到了两个语法的输出几乎相同的步骤,除了一些边缘情况。但是,有些文件的解析时间非常长(即使使用 SLL 预测模式和 BailOutStrategy),所以我想知道如何找到应该首先修复的规则。
我已经使用 Parser#setProfile() 收集了一些统计数据,但我不知道如何解释每个 DecisionInfo 对象中的结果。有没有关于如何开始优化大型 ANTLR4 语法并找到先追哪只兔子的好文档?
由于我不知道要在 DecisionInfo 对象中寻找什么,下面是我找到的内容,它帮助我将解析时间缩短了至少一个数量级。
首先,我使用 org.antlr.v4.runtime.Parser.setProfile(boolean profile)
启用语法分析,然后使用 org.antlr.v4.runtime.Parser.getInterpreter().setPredictionMode(PredictionMode.SLL)
对数千个文件执行解析器,并浏览预测时间最长的规则:
Arrays.stream(parser.getParseInfo().getDecisionInfo())
.filter(decision -> decision.timeInPrediction > 100000000)
.sorted((d1, d2) -> Long.compare(d2.timeInPrediction, d1.timeInPrediction))
.forEach(decision -> System.out.println(
String.format("Time: %d in %d calls - LL_Lookaheads: %d Max k: %d Ambiguities: %d Errors: %d Rule: %s",
decision.timeInPrediction / 1000000,
decision.invocations, decision.SLL_TotalLook,
decision.SLL_MaxLook, decision.ambiguities.size(),
decision.errors.size(), Proparse.ruleNames[Proparse._ATN.getDecisionState(decision.decision).ruleIndex])))
然后使用相同的 lamba 进行最高最大前瞻,除了:
filter(decision -> decision.SLL_MaxLook > 50).sorted((d1, d2) -> Long.compare(d2.SLL_MaxLook, d1.SLL_MaxLook))
这给了我 4 条规则,其中大部分时间都花在了上面,在这种情况下,这足以看到必须更改的内容(通过知道在哪里寻找问题)。