java编写正则表达式_如何用Java编写最快的表达式评估器之一

java编写正则表达式

当然,标题有点吸引人,但确实如此(您当然不相信自己没有伪造自己的基准,但这是另一回事了)。

因此,上周我正在寻找一个小型且可用的库来评估数学表达式。 我几乎直接偶然发现了这个stackoverflow帖子 。 推荐的库( Expr )确实非常快,几乎满足了我的所有需求。 但是,它没有提供限制变量范围的功能(所有内容都位于VM的一个全局命名空间中)。

因此,我做到了,通常这是我们不应该做的:我重新发明了轮子,并编写了自己的解析器/评估器。 无论如何,这是一个下雨的星期六,所以我认为一个小的递归降序解析器,一个可以简化并最终计算表达式以及一个用于管理变量的小助手的AST似乎并不重要。 事实并非如此。 我有一个初步的实现,并运行得非常快。 一旦进行了一些测试,使我相信它可以正确地计算所有内容,那么我想知道与原始文章中提到的其他库相比,评估器的速度如何。 由于没有手动优化每个内部循环和所有内容,因此我没有太大期望,毕竟有些库还是商业库。 因此,当我查看结果时,我感到非常惊讶。 下面的列表显示了一个微基准,该基准使用相应的库评估相同的表达。 我的库parsii的测量是使用最终版本完成的,该版本执行了一些简化操作,例如预先评估常量表达式。 但是,没有像字节码生成之类的“黑魔法”或类似的事情发生。

为了进行性能测量,对表达式“ 2 +(7 – 5)* 3.14159 * x ^(12-10)+ sin(-3.141)”进行了评估,其中x从0到1000000。对JIT进行10次加热。然后再次执行15次,平均执行时间为:

  • PARSII :28.3毫秒
  • 曝光 :37.2毫秒
  • MathEval :7748.5毫秒
  • JEP :647.0毫秒
  • MESP :220.8毫秒
  • JFEP :274.3毫秒

现在,我敢肯定,这些库中的每一个都有各自的优势,因此无法直接进行比较。 仍然令人惊讶的是,一个简单的实现可以很好地竞争。

对于那些不太了解编译器构造的人,下面简要介绍一下它的工作原理:

就像任何解析器或编译器一样,parsii使用经典的方法是使用分词器 ,该工具将字符流转换为令牌流。 因此,作为字符数组的“ 4”,“,”,“ +”,“”,“ 3”,“,”,“ *”,“ 8”的“ 4 + 3 * 8”将被转换为:

  • 4(整数)
  • +(符号)
  • 3(整数)
  • *(符号)
  • 8(整数)

令牌生成器查看当前字符,然后确定正在查看的令牌类型,然后读取属于该令牌的所有字符。 每个标记都有其类型,文本内容,并且知道其起始位置(行和字符)。 网上有很多深入的教程,因此在这里我不再赘述。 您可以看一下源代码,但是正如我所说的,它只是一个简单的基本实现。

解析器将经典的递归降序解析器转换为AST(抽象语法树),然后可以对其进行评估。 这是构建解析器的最简单方法之一,因为它完全是手工编写的,而不是由工具生成的。 这样的解析器基本上包含每个语法规则的方法。

再次有很多此类解析器的教程。 但是,大多数示例遗漏的是正确的错误处理。 除了正确和快速地解析表达式之外,良好的错误处理是良好的解析器的主要方面之一。 这并不难:正如您在源代码中看到的那样,解析器在解析表达式时从不抛出异常。 将收集所有错误,并且解析器将继续尽可能长的时间。 即使在出现第一个错误后,仍无法正确评估生成的AST,但仍应继续进行,并且一次运行应报告尽可能多的错误,这一点很重要。 令牌生成器使用相同的方法,因为将格式错误的令牌(例如带有两个小数分隔符的十进制数字)报告给同一错误列表。

评估AST是解析表达式的结果,这非常容易。 语法树的每个节点都有一个评估方法,该方法将由其父节点从根节点开始调用。 此处eval的结果是对表达式求值的结果。 可以在BinaryOperation中找到这种方法的基本示例,它表示+,-,*等操作。

为了稍微缩短评估时间,执行了三个优化:

首先,在解析AST之后,在根节点上调用一种称为simple的方法,该方法会传播到每个子节点。 然后,每个节点决定是否可以找到自己的子表达式的更简单表示形式。 例如:对于二进制运算 ,我们检查两个操作数是否都是常数(数字)。 在这种情况下,我们对表达式求值并返回一个包含操作结果的新常量。 对于所有参数都恒定的函数,也可以这样做。

当在表达式中使用变量时,完成第二次优化。 幼稚的方法是使用映射并在需要时读取或写入变量的值。 尽管这确实可行,但是在执行时需要进行很多查找。 因此,我们有一个名为Variable的特殊类,其中包含变量的名称和数值。 解析表达式时,将在范围(基本上只是一个映射)中查找一次该变量,然后从现在开始使用。 由于每个查找返回相同的实例,因此在评估表达式时对变量的访问与对字段的读取或写入一样便宜,因为我们仅访问Variablevalue字段。

第三次也是最后一次优化可能不会经常发挥作用。 但由于易于实现,因此还是可以实现。 它基本上被称为“惰性求值”,并在调用函数时使用。 函数不会自动求值其所有参数,然后自动执行函数调用。 它宁愿看论点,也可以凭自己决定要评估哪个论点,而不要决定。 可以在if函数中找到使用它的示例。

parsii是根据MIT许可获得许可的。 可以在GitHub上找到所有源代码以及预编译的jar。

参考: 如何在Andy的Software Engineering Corner博客上从我们的JCG合作伙伴 Andreas Haufler编写Java中最快的表达式评估器之一 。

翻译自: https://www.javacodegeeks.com/2014/01/how-to-write-one-of-the-fastest-expression-evaluators-in-java.html

java编写正则表达式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤题库】陕西师范大学210029 幼儿园游戏(学前儿童游戏)作业

《幼儿园游戏》作业 一、单选题 1、我国传统的游戏材料“七巧板”在国外称为( )。 2、原始人的游戏形式是高度融合的,主要表现为想象性游戏和( )两种游戏。 3、教育对幼儿具有( )的价值。 4、亲…

【渝粤题库】陕西师范大学292391 金融机构管理 作业(专升本)

一、单项选择题 1、“经理国库、充当最后贷款人”表示中央银行在行使( )职能。 A.调节职能 B.服务职能 C.管理职能 D.控制职能 2、我国国民经济核算新体系由( )组成。 A.资产负债表和资金流量表 B.国际收支…

matlab图像采集程序,用摄像头连续采集、保存图像源程序

写了一个在matlab2006上用摄像头连续采集、保存图像源程序。运行imaq_test.m文件后,弹出保存对话框,指定一个存盘目录,选定保存格式(如.jpg),输入主文件名(如aqim),点击开始采集按钮,将以设定的频率采集图像…

【渝粤题库】陕西师范大学400010 当代西方社会思潮评析 作业(专升本)

《当代西方社会思潮评析》作业 一、谈谈你对下列概念的理解 1、第三条道路 2、生态社会主义 3、后殖民主义 4、未来主义 5、新自由主义 6、新自由主义 7、后现代主义 8、女权社会主义 9、市场社会主义 10、分析的马克思主义 二、简要回答下列各题 1、“兰格模式”的主要内容与理…

Spring-Boot 2.1.x和主要的bean定义

我最近将应用程序从Spring Boot 1.5.X迁移到Spring Boot 2.X ,发现覆盖Spring Bean定义存在问题。 其中一种配置是在Kotlin中遵循的: Configuration class DynamoConfig {Beanfun dynamoDbAsyncClient(dynamoProperties: DynamoProperties): DynamoDbAs…

【渝粤题库】陕西师范大学600011 结构化学作业(专升本)

《结构化学》作业 一.填空题 1.测不准关系的正确表达式是(  ) 2.氢原子的波函数ψ可以写成径向部分Rnl与角度部分(  )的乘积。 3.在同核双原子分子中,两个2p轨道组合产生两个(  )轨道。 4…

php 5.5.7.tar.gz,编译 php-5.5.26.tar.gz

需要GD库大于2.1版本编译GD库请参考文章 安装GD库./configure --prefix/usr/local/php/ --with-config-file-path/usr/local/php/etc/ --with-libxml-dir/usr/local/libxml2/ --with-jpeg-dir/usr/local/jpeg/ --with-freetype-dir/usr/local/freetype/ --with-gd --with-mcry…

国家开放大学2021春1009离散数学(本)题目

教育 教育 试卷代号:1009 2021年春季学期期末统一考试 离散数学(本) 试题 2021年7月 一、单项选择题(每小题4分,本题共20分) 1.若集合A{1,2,3,4},则下列表述…

国家开放大学2021春1107传感器与测试技术题目

教育 教育 试卷代号:1107 2021年春季学期期末统一考试 传感器与测试技术 试题 2021年7月 一、单项选择题(12小题,每小题3分,共36分) 1.电阻应变片的绝缘电阻是指已粘贴的应变片的( )间的电阻值…

php 有 stringbuffer,String、StringBuffer、StringBulider三者介绍

三者都实现了CharSequence接口,因此CharSequence可认为是一个字符串的协议接口1.String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁;我们常常定义的时候 S…

【渝粤题库】广东开放大学 会展策划 形成性考核

选择题 题目:会展的()是指企业和品牌利用展览会不断翻新花样,宣传自己品牌。 题目:目前世界上规模最大、影响力最广的综合展是()。 题目:以下属于宣传类展览会的是(&…

【渝粤题库】广东开放大学 传播学理论与实务 形成性考核

选择题 题目: R语言是一种用于数据统计与分析的一种商用、收费的工具 题目:1、让受众透过媒介经常看到你,可以增强(B )。 题目:4、以下不属于非语言符号的是 (A ) 题目:6、(D &…

php生成网页按钮,JavaScript实现自动生成网页元素功能(按钮、文本等)_javascript技巧...

创建元素的方法:1、利用createTextNode()创建一个文本对象2、利用createElement()创建一个标签对象3、直接利用容器标签中的一个属性:innerHTML-----本质上改该标签容器中的“html代码”,不是我们认为的对象树的操作详解代码:这是…

【渝粤题库】广东开放大学 静态网页技术 形成性考核

选择题 题目:通常网页的首页被称为()。 答案: A、网页 B、主页 C、网址 D、页面 题目:网页的基本语言是( )。 答案: A、HTML B、XML C、JavaScript D、VBScript 题目:下列…

adf 自动输稿器_在ADF实体PK属性中使用MySQL自动增量PK列

adf 自动输稿器大家好。 继续进行ADF MySQL解决方法系列,今天我们将看到需要做些什么才能将MySQL PK自动增量列与ADF实体PK属性一起使用。 如果使用的是Oracle数据库,则可以使用oracle.jbo.domain.DBSequence以及序列和触发器来立即进行操作。 为简单起…

matlab rbf核函数,RBF高斯径向基核函数-svm

RBF高斯径向基核函数(单值:两个点相似性)XVec表示X向量。||XVec||表示向量长度。r表示两点距离。r^2表示r的平方。k(XVec,YVec) exp(-1/(2*sigma^2)*(r^2)) exp(-gamma*r^2)...... 公式-1这里, gamma1/(2*sigma^2)是参数, r||XVec-YVec||实际上,可看作是计算2个点X…

【渝粤题库】广东开放大学 人力资源本 形成性考核

选择题 题目:中国规定的最低就业年龄是( ) 答案: A、15岁 B、16岁 C、14岁 D、18岁 题目:关于人力资源管理环境的辨识,变化小且数量大的是? 答案: A、高度不确定性的环境 B、中低不确…

【渝粤题库】广东开放大学 会展项目实践 形成性考核

选择题 题目:会展行业是一个()的服务行业。 答案: A、行业精英型 B、知识含量小 C、劳动密集型 D、劳动稀疏型 题目:会展业具有()和社会效益。 答案: A、集聚效应 B、文化效益 C、生…

python string 方法,python字符串的方法与操作大全

一:字符串的方法与操作*注意:首字母为l的为从左边操作,为r的方法为从右边操作1.__contains__()判断是否包含判断指定字符或字符串是否包含在一个字符串内,返回值为true或者false运行结果:TrueTrueFalse作用和in相似运行结果&#…

探索适用于Apache Spark的Spline Data Tracker和可视化工具(第1部分)

最近引起我注意的一个有趣且充满希望的开源项目是Spline ,它是由Absa维护的Apache Spark的数据沿袭跟踪和可视化工具。 该项目由两部分组成:一个在驱动程序上工作的Scala库,该驱动程序通过分析Spark执行计划来捕获数据沿袭,并提供…