Llvm 快速布尔表达式计算器
我有一个应用程序,包括一个3运算符(&|!)布尔表达式计算器,带有变量和常量。一般来说,表达式不会太长(可能最多50个术语,但通常要少得多)。可以有很多表达式-我预计上限约为一百万。目前我有一个手工编写的解析器,它带有一个非常简单的计算器,可以递归地遍历解析树。一个约束是,这必须是C++调用的。我无法分享不同的表达方式。我想调查一下加速这件事 我看到两种研究途径Llvm 快速布尔表达式计算器,llvm,antlr4,expression-evaluation,Llvm,Antlr4,Expression Evaluation,我有一个应用程序,包括一个3运算符(&|!)布尔表达式计算器,带有变量和常量。一般来说,表达式不会太长(可能最多50个术语,但通常要少得多)。可以有很多表达式-我预计上限约为一百万。目前我有一个手工编写的解析器,它带有一个非常简单的计算器,可以递归地遍历解析树。一个约束是,这必须是C++调用的。我无法分享不同的表达方式。我想调查一下加速这件事 我看到两种研究途径 添加共享并存储指示表达式节点是否已计算的状态 提取公共子表达式 我还希望代码生成方法比解析树或类似结构的解释性方法更快。生成一些C++
有什么建议吗?尽管我很想建议使用ANTLR4,但我担心它无法满足您的性能需求。它的自适应LL(*)算法有很多秘密,尽管有一些常见的技巧可以提高其性能,但在运行时简单地跟踪ANTLR4解释器表明,除非您当前的表达式计算器效率非常低,否则它可能比ANTLR4快,这是一个工业级引擎,用来支持比你复杂得多的语法。当LALR(1)DFA shift REDUCT引擎不支持我的语法时,我使用ANTLR,并以性能损失换取ANTLR4的额外解析能力。据我所知,你的问题更多的是关于更快的表达式计算,而不是关于更快的表达式解析。所以我的答案将集中在前者。毕竟,解析不应该成为瓶颈,因为您的表达式语言看起来足够简单,可以为它实现手动调优的解析器 <> P>因此,为了加速您的评估,可以考虑使用LLVM执行公式的JIT。也就是说,给定公式
F
,您可以(相对)轻松地生成相应的LLVM IR并直接对其进行评估。就是这样。IR代码生成是在一个C++类中实现的。
请注意,您提到的布尔表达式是该解算器支持的SMT语言的子集。此外,您可以轻松地调整LLVM优化器的攻击性
然而,IR生成和优化有其开销。因此,如果给定公式的评估频率不足以摊销初始间接费用,那么我建议改为直接解释。在本例中,您可以寻找找到结构相似性和公共子表达式的机会。parse和lex的运行时不应该是问题。这是一个独立的阶段,与反复进行的评估不同,可能需要几天的运行时间。因此,即使是几个小时的解析阶段也不会有问题。评估速度是关键。啊,我明白了。我误解了你的问题。ANTLR中的评估可能非常有效。有一种叫做Mu的语法,我用它作为运行时表达式解释器的基础。