高性能 java 库 wast - JSONPath 性能测试
关于JSONPath,很早之前本人实现了一个按需解析模型JSONNode,路径规则参考xpath(不支持递归搜索),后来才知道有个JSONPath规范,路径规则懒得改了,几个月前做JSON优化,狠心优化了一个版本,大部分常用的JSONPath功能都已支持包括递归,性能也大幅度提升(主要依赖于JSON优化带来的提升)。
早前和fastjson2对比的测试地址: xiaoch0209/wast-jmh-test
本次测试加入了另一个高性能JSONPath库snack3参与测试
测试环境: window11 + i9 + 32g JDK8 单线程
版本
<dependency>
<groupId>io.github.wycst</groupId>
<artifactId>wast</artifactId>
<version>0.0.21</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.53</version>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>snack3</artifactId>
<version>3.2.122</version>
</dependency>
完整测试代码: src/main/java/com/jmh/test/json/path/JSONPath2Test.java · xiaoch0209/wast-jmh-test
测试结果(每毫秒运行次数)
Benchmark Mode Cnt Score Error Units
JSONPath2Test.fastjsonReaderAuthors thrpt 5 1051.292 ± 19.083 ops/ms
JSONPath2Test.fastjsonReaderPrices thrpt 5 1089.031 ± 21.456 ops/ms
JSONPath2Test.fastjsonReaderTop2Author thrpt 5 1287.563 ± 19.824 ops/ms
JSONPath2Test.snack3Authors thrpt 5 460.155 ± 4.650 ops/ms
JSONPath2Test.snack3Prices thrpt 5 462.212 ± 7.238 ops/ms
JSONPath2Test.snack3Top2Authors thrpt 5 445.641 ± 2.799 ops/ms
JSONPath2Test.wastAuthors thrpt 5 2744.988 ± 24.966 ops/ms
JSONPath2Test.wastPrices thrpt 5 2521.418 ± 16.674 ops/ms
JSONPath2Test.wastTop2Authors thrpt 5 5635.949 ± 83.514 ops/ms
wast >> fastjson >> snack3
当前场景下wast性能均远高于其他2个库(不过在毫秒这个级别下运行速度都已经很快了)
另外wast对JSONPath条件查找使用内置的表达式引擎支持,条件使用中括号包起来,语法比JSONPath更简单直观(个人感觉)
JSONPath多条件语法: $..person[?(@.age > 18 && @.name == 'John')]
JSONNode多条件语法: //person[age>18&&name=='John']
以下摘自wiki部分案例代码
// 5.获取作者J. R. R. Tolkien的书
List<JSONNode> filterBooks = JSONNode.collect(source, "/store/book/*[author=='J. R. R. Tolkien']");
System.out.println(JSON.toJsonString(filterBooks));
// 6.获取作者J. R. R. Tolkien的书的价格
double price = JSONNode.first(source, "/store/book/*[author=='J. R. R. Tolkien']/price", double.class);
System.out.println(price);
// 7.获取作者Herman Melville的同时价格小于10(多条件过滤),过滤表达式参考Expression语法
Book book = JSONNode.first(source, "/store/book/*[author=='Herman Melville'&&price<10]", Book.class);
System.out.println(JSON.toJsonString(book));
Book book2 = JSONNode.firstIfEmpty(source, "/store/book/*[author=='Herman Melville'&&price>=10]", Book.class, null);
System.out.println(book2); // NULL
// 8.获取价格最高的一本书的书名(注意仅限于在某一个集合下),注意引入了parent内置的变量
String bookName = JSONNode.first(source, "/store/book/*[price==parent.max('price')]/title", String.class);
System.out.println(bookName);
// 9.获取存在isbn属性的书名
System.out.println(JSONNode.collect(source, "/store/book/*[isbn]/title"));
// 10.获取所有的book节点
System.out.println(JSONNode.collect(source, "//book/*"));
更多使用案例: wiki JSONNode
wast源码地址
- gitee: https://gitee.com/xiaoch0209/wast
- github: https://github.com/wycst/wast