数据加工DSL编译优化:搜索特定领域语言

简介: 背景面向数据加工领域的搜索DSL(特定领域语言,Domain-Specific Language)无需使用者编写较为复杂的通常程序语言,通过简洁的DSL即可实现复杂的搜索需求,具有较好的用户体验。搜索算子语法支持较为丰富,传统方案采用遍历AST(抽象语法树,Abstract Syntax Tree)的方式,根据当前的标识符类型执行对应操作。上述设计也就是常说的“解析执行”方案,由于每次都需要 “判

背景

面向数据加工领域的搜索DSL(特定领域语言,Domain-Specific Language)无需使用者编写较为复杂的通常程序语言,通过简洁的DSL即可实现复杂的搜索需求,具有较好的用户体验。搜索算子语法支持较为丰富,传统方案采用遍历AST(抽象语法树,Abstract Syntax Tree)的方式,根据当前的标识符类型执行对应操作。上述设计也就是常说的“解析执行”方案,由于每次都需要 “判断标识符类型”,执行效率较慢。

本文,提出一种高效的数据加工搜索特定领域语言,不仅采用“编译执行”的设计方案,避免了重复“判断标识符类型”,直接搜索表达式对应操作,而且采用了语义等价转换的方式以尽可能构建较优的运行时数据结构,不仅保证了语义的正确性,而且翻译得到的运行时代码执行效率较高。

怎么实现的?

本文提出了一种高效的数据加工搜索特定领域语言,具有灵活和丰富的语义,“编译执行”避免了类型判断等重复性操作,通过语义等价转换,进而使用了“较优的运行时数据结构”,执行速度较快,数据处理能力好,吞吐率较高。系统模块设计分为四部分:搜索语义定义、抽象语法树构造、语义等价优化、运行时代码生成。

   A)搜索语义定义,编写搜索语义对应的Antlr4对应的语法文件。

1.全文搜索,语法格式为“字符串”, 同时字符串中间存在空格,则表示字符串是或逻辑关系。例如:e_search("active error")。

2.字段搜索,语法格式为“字段:字符串”,同时字符串中间存在空格,则表示字符串是或逻辑关系。例如:e_search("status: active")。

3.完全匹配, 语法格式为“字段=="字符串"”。例如:e_search('author== "john smith"')。

4.正则匹配,语法格式为“字段~=字符串”。例如:e_search('content~="正则表达式"')。

5.通配符搜索,星号(*)匹配零个或多个字符,问号(?)匹配一个字符。例如:e_search("status: active*test")。

6.搜索值转义,星号(*)或问号(?)需要使用反斜线(\)转义。例如:e_search('status: "\*\?()[]:="')。

7.字段名转义,特殊字符用反斜线(\)转义。例如:e_search("__tag__\:__container_name__: abc")。

8.数字,支持数字大小和范围的搜索匹配。例如:e_search('count: [100, 200]'),e_search('age >= 18')。

9.使用关系运算符,支持not、and和or操作。例如:e_search("abc OR xyz"),e_search("abc and not (xyz and not zzz)")。

   B)抽象语法树构造,用于将作业的DSL解析并改写为语义一致的AST(抽象语法树,Abstract Syntax Tree)。

1.将DSL采用词法语法工具Antlr4解析成为AST。

2.采用监听器模式,访问AST节点,并在exist方法中转换构造语义更加完备的AST。比如:将二目逻辑运算符OR,转换为多目逻辑运算符OR,以此方便后续的语义优化。

   C)语义等价优化,在保证语义相同的前提下,尽量转换为执行效率更高的操作,也就是为转换为高效的运行时代码做准备。

1.通配符处理。前后通配符去除,通配符转换为正则,以此去除较为常见的DSL编写手误,此优化为一对一转换,较为简单。

2.表达式优先级排序。不同表达式的计算复杂度是不同的,算术运算相等比较运行较快,子串搜索次之,正则匹配计算复杂度较高,由此将算术运算相等比较尽可能前置,正则匹配尽可能后置,能够得到较好的执行效果。

3.公共字段提取。每个人的编写DSL习惯不同,有些搜索表达式中充斥着大量的重复字段字段,比如对某个字段的子串或运算,如果将这个公共字段提取,这个字段取值只需执行一次即可,而且这个字段的操作可以进一步转换为更高效的运行时数据结构。

4.复杂逻辑表达式合并。当复杂逻辑表达式元素超过阈值时,可以等价转换为高效的运行时数据结构,大量的算术运算相等比较可以转换为集合in操作,大量的子串搜索可以转换为AC自动机,大量的正则匹配可以合并为同一条正则。

注意:由于语义等价优化会改变原AST的结构,进而可能又会产生新的语义等价优化点,因此,本文设计语义等价优化迭代次数为2。

   D)运行时代码生成,将AST转换为能够可以执行的运行时C++代码。此步骤较为简单为AST和C++类结构的一对一翻译,采用拼接字符串的方式翻译为C++类(编译器的一种执行方式,把AST翻译为程序代码),然后将翻译之后的运行时代码打包既可以运行。

搜索特定领域语言参照:

                              

有哪些实际价值?

1)语义灵活丰富:搜索特定领域语言支持多种搜索语义,并且这些表达式均可嵌套,进而可以灵活地实现客户复杂需求。

2)优化门槛低:优化过程极为简单,完全由后台程序自动实现,客户无需深入分析及手动优化。

3)执行速度快:避免了类型判断等重复性操作,并且采用了高效的运行时数据结构,提高了运行时的执行速度,优化了事件吞吐率和实时性。

相关文章
|
6天前
|
自然语言处理 JavaScript 前端开发
使用Pagefind为VitePress文档添加离线全文搜索能力
前言 VitePress 相信大家都或多或少听说过或者用过了 默认 UI相比 VuePress2.x 好看,启动速度也快(由Vite驱动,当然VuePress也可以切换构建引擎至Vite) 做内容定制也相对简单,笔者的很多静态文档站点(使用VuePress1.x),文章内容多的时候启动非常的慢,于是就从之前的 VuePress 迁移到了 VitePress,并做了一个博客主题 @sugarat/theme => 之前也有过介绍一个简约风的VitePress博客主题 但是 VitePress 官方目前还没有内置开箱即用的搜索能力(相关PR还在施工中)
|
8月前
|
算法 索引
阿里云 Elasticsearch 使用 RRF 混排优化语义查询结果对比
Elasticsearch 从8.8版本开始,新增 RRF,支持对多种不同方式召回的多个结果集进行综合再排序,返回最终的排序结果。之前 Elasticsearch 已经分别支持基于 BM25 的相关性排序和向量相似度的召回排序,通过 RRF 可以对这两者的结果进行综合排序,可以提升排序的准确性。
1662 0
|
6月前
|
机器学习/深度学习 自然语言处理 安全
【网安专题11.8】14Cosco跨语言代码搜索代码: (a) 训练阶段 相关程度的对比学习 对源代码(查询+目标代码)和动态运行信息进行编码 (b) 在线查询嵌入与搜索:不必计算相似性
【网安专题11.8】14Cosco跨语言代码搜索代码: (a) 训练阶段 相关程度的对比学习 对源代码(查询+目标代码)和动态运行信息进行编码 (b) 在线查询嵌入与搜索:不必计算相似性
180 0
|
6天前
|
数据采集 存储 搜索推荐
使用Python构建自定义搜索引擎:从数据抓取到索引与搜索
使用Python构建自定义搜索引擎:从数据抓取到索引与搜索
117 0
|
8月前
|
存储 索引
ES 分布式搜索的运行机制
ES 分布式搜索的运行机制
29 1
ES 分布式搜索的运行机制
|
10月前
|
数据采集 运维 前端开发
简洁高效的单号转换工具:提升编程效率
简洁高效的单号转换工具:提升编程效率
316 0
|
12月前
|
机器学习/深度学习 自然语言处理 搜索推荐
「语义搜索」搜索引擎过时了,“寻找引擎”流行起来
「语义搜索」搜索引擎过时了,“寻找引擎”流行起来
|
存储 编译器 C#
【C#基础】C# 基础语法解析
编程语言 C# 基础语法的介绍 。
83 0
【C#基础】C# 基础语法解析
|
数据库
通过互联网搜索接口更新拼写语法库的设计
通过互联网搜索接口更新拼写语法库的设计
53 0
|
消息中间件 存储 JSON
一种面向数据加工DSL的代码翻译算法
背景面向数据加工领域的DSL(特定领域语言,Domain-Specific Language)无需使用者编写较为复杂的通常程序语言,具有较好的用户体验,应用较为广泛。如何将DSL翻译为机器可执行的程序是每种DSL均需面对的问题,并且传统的DSL翻译通常采用直译的方式,运行时执行效率较低。本文,提出一种面向数据加工领域语言的代码翻译算法,针对不同的DSL函数分别设计了代码翻译方案,不仅保证了语义的正
一种面向数据加工DSL的代码翻译算法