Java 为什么Jackson流式API很慢?
根据Jackson流媒体API文档: 如果显式重写所有转换以使用流API而不是数据绑定,则可以将吞吐量提高30-40%;这不需要对实际生成的JSON进行任何更改 全文如下: 但是,根据我的基准测试,在最好的情况下,吞吐量提高了15-20%,对于编写复杂对象,吞吐量甚至降低了约23% 我做错什么了吗?为什么具有流式api的复杂对象的写操作比使用在流式api之上工作的ObjectMapper慢 非常有趣的是,Jackson流媒体性能的下降对于java11/12来说更为显著(与java11/12的24%相比,下降了约2%) 配置:Java 为什么Jackson流式API很慢?,java,jackson,java-11,jmh,jackson-modules,Java,Jackson,Java 11,Jmh,Jackson Modules,根据Jackson流媒体API文档: 如果显式重写所有转换以使用流API而不是数据绑定,则可以将吞吐量提高30-40%;这不需要对实际生成的JSON进行任何更改 全文如下: 但是,根据我的基准测试,在最好的情况下,吞吐量提高了15-20%,对于编写复杂对象,吞吐量甚至降低了约23% 我做错什么了吗?为什么具有流式api的复杂对象的写操作比使用在流式api之上工作的ObjectMapper慢 非常有趣的是,Jackson流媒体性能的下降对于java11/12来说更为显著(与java11/12的24
- 8 CPU
- 64 GB内存
- 操作系统版本16.04.1 LTS(Xenial Xerus)
- Docker版本18.03.0-ce,版本0520e24
- 预热:10次迭代,每次10秒
- 测量:10次迭代,每次10秒
- 线程:1个线程,将同步迭代
- 虚拟机选项:-XX:+UseG1GC-server-Xmx4096m-Xms4096m
- 单位:行动组
//普通对象
公共体育课{
长id;
字符串名;
}
//复杂对象
公开课活动{
长id;
长运动ID;
字符串名;
日期开始时间;
布尔运算;
布尔AllowLiveBoting;
上市市场;
列出与会者名单;
}
公务舱市场{
长id;
长事件;
字符串名;
布尔运算;
布尔AllowLiveBoting;
双重价值;
整数优胜者;
列出跑步者名单;
}
公开课跑者{
长id;
长事件;
长期市场化;
长期活动参与者;
字符串名;
布尔撤回;
双重价值;
}
公开课活动参与者{
长id;
长事件;
字符串participantName;
字符串名称;
字符串trainerName;
整数;
}
代码
@基准测试
@基准模式(模式吞吐量)
public void complexJacksonStreamWrite(执行计划计划,黑洞)引发IOException{
Event=plan.getBigObjects();
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
try(JSONG发电机)=
plan.getFactory().createGenerator(
outputStream,JsonEncoding.UTF8){
generator.writeStartObject();
generator.WriteEnumberField(“id”,event.getId());
//填充rest属性
generator.writeFieldName(“事件参与者”);
generator.WriteStarray();
对于(int i=0;i
如何跑步
爪哇8
docker run-it volkodav/JavaJackson基准:java8
爪哇11
docker run-it volkodav/JavaJackson基准:java11
爪哇12
docker run-it volkodav/java jackson基准:java12
源代码:
更新 在@Jom Vernee发表评论后,他建议设置ByteArrayOutputStream的大小-Jackson流式写入的性能提高了约10%
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(60_000);
复杂
普通的
您是否尝试过预先调整输出流的大小?考虑到这两种方法在分配压力上的差异,我猜内部缓冲区的重新分配工作正在进行。初始大小仅为32字节,用完时会加倍,但在这种情况下必须复制内部缓冲区。是的,你有一个非常有效的观点!我应用了您的建议,性能提高了约10%,但仍然比ObjectMapper慢;(