# jsonvisitor **Repository Path**: flowerlan/jsonvisitor ## Basic Information - **Project Name**: jsonvisitor - **Description**: 基于ANTLR4实现简单JSON解析获取特定字段 - **Primary Language**: Unknown - **License**: BSD-2-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-08-11 - **Last Updated**: 2024-08-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # jsonvisitor #### 介绍 简单json解析器,基于ANTLR 4实现。 该项目原本的目标是实现一个json解析器,解析JSON数据,获取json object中指定名称的字段,对于不关注的字段都跳过。 代码完成后,执行性能测试,发现不比fastjson直接解析整个JSON数据快多少。 经过反复比较,最终选择使用 fastjson 的词法解析器(JSONScanner)提供的`seekObjectToField(long fieldNameHash, boolean deepScan)`方法来实现字段查找功能。比ANTLR 4生成的词法解析器快一个数量级。 具体数据请执行性能测试。 #### 系统要求 | phase | JDK version | | ----- | ----------- | | 运行 | JDK 7 | | 编译 | JDK 8 | #### 语法说明 语法/词法定义:[src/main/java/com/gitee/l0km/jsonvisitor/parser/JSON.g4](src/main/java/com/gitee/l0km/jsonvisitor/parser/JSON.g4) #### 语法解析 语法解析调用实现 [com.gitee.l0km.jsonvisitor.JsonVisitorParser](src/main/java/com/gitee/l0km/jsonvisitor/JsonVisitorParser.java),parse系列方法可以从不同的输入源获取文本解析. 解析调用示例: ```java import static net.gdface.utils.SimpleLog.log; import static com.gitee.l0km.jsonvisitor.JsonVisitorParser.PARSER; import static com.gitee.l0km.jsonvisitor.parser.JSONParser.RULE_string; @Test public void test1() { String jsonstr = "{\"tokenId\":0}"; Object parsed = PARSER.pairVisit(jsonstr, "tokenId", RULE_string); log("parsed:{}",parsed); assertNull(parsed); } ``` ## 性能测试 命令行执行,即可以执行性能测试,输出比较结果: ```bash mvn -Dtest=PerformanceTest#test -DskipTests=false -Djsonfile="16650_end.json" test ``` > -Djsonfile="16650_end.json" 用于指定用于测试的JSON数据文件,如果不指定使用默认数据文件: parserTest.json 输出如下: ``` ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.gitee.l0km.jsonvisitor.PerformanceTest [main] (Timecost.java:36) ==fastjson 解析测试[基准] [main] (Timecost.java:39) TIME COST: [79.0963ms]<<<首次执行时间 [main] (Timecost.java:39) TIME COST: [5.7771ms]<<<第二次执行时间 [main] (Timecost.java:41) TOTAL TIME COST: [164.3285ms] [main] (Timecost.java:42) AVG TIME COST: [1.6433ms] for 100 times<<<100次测试平均值 [main] (Timecost.java:36) ==Antlr4 语法树(JSONVisitor)遍历解析测试 [main] (Timecost.java:39) TIME COST: [95.7972ms]<<<首次执行时间 [main] (Timecost.java:39) TIME COST: [29.3285ms]<<<第二次执行时间 [main] (Timecost.java:41) TOTAL TIME COST: [940.5354ms] [main] (Timecost.java:42) AVG TIME COST: [9.4054ms] for 100 times<<<100次测试平均值 [main] (Timecost.java:36) ==Antlr4 词法分析器(Lexer)解析测试 [main] (Timecost.java:39) TIME COST: [29.8893ms]<<<首次执行时间 [main] (Timecost.java:39) TIME COST: [5.8947ms]<<<第二次执行时间 [main] (Timecost.java:41) TOTAL TIME COST: [653.2166ms] [main] (Timecost.java:42) AVG TIME COST: [6.5322ms] for 100 times<<<100次测试平均值 [main] (Timecost.java:36) ==fastjson词法分析器(Lexer)解析测试 [main] (Timecost.java:39) TIME COST: [6.7722ms]<<<首次执行时间 [main] (Timecost.java:39) TIME COST: [3.6805ms]<<<第二次执行时间 [main] (Timecost.java:41) TOTAL TIME COST: [220.0746ms] [main] (Timecost.java:42) AVG TIME COST: [2.2007ms] for 100 times<<<100次测试平均值 [main] (Timecost.java:36) ==fastjson 词法分析器(JSONScanner)字段名查找(seekObjectToField)测试 [main] (Timecost.java:39) TIME COST: [5.1285ms]<<<首次执行时间 [main] (Timecost.java:39) TIME COST: [2.7439ms]<<<第二次执行时间 [main] (Timecost.java:41) TOTAL TIME COST: [76.3522ms] [main] (Timecost.java:42) AVG TIME COST: [0.7635ms] for 100 times<<<100次测试平均值 Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.42 sec ``` 不同的JSON数据得到的结果不一样, `16650_end.json`数据中关注的`tokenId`字段在JSON的末尾,`fastjson 词法分析器(JSONScanner)字段名查找(seekObjectToField)测试`测试结果比`fastjson解析[基准]`快一倍。 如果使用`16650_header.json`数据(关注的`tokenId`字段是JSON的第一个字段),`fastjson 词法分析器(JSONScanner)字段名查找(seekObjectToField)测试`测试结果比`fastjson解析[基准]`快两个数量级,因为它找到关注的字段后,就不需要再解析后面的数据。