spring - 为什么Spring MVC json序列化比手动调用jackson慢10倍?

标签 spring performance spring-mvc jackson

使用 apachebench 和“ab -k -c 50 -n 1000000”选项(50 个并发线程)显示以下 2 种方法(手动和 spring 管理的序列化)之间的性能差异为 10 倍。通过配置Spring序列化是否可以达到相同的性能?

我正在 Windows 7、JDK8、i7-6700 上运行测试。嵌入式 Tomcat,与 UndertowJetty 的结果也类似。类似的 WildFly 10 JAX-RS 示例应用程序性能产生与手动 Spring 应用程序类似的结果,因此我认为 Spring 自动模式没有理由如此缓慢。

完整源代码:

@SpringBootApplication
@Controller
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  ObjectMapper mapper = new ObjectMapper(new JsonFactory());

  @RequestMapping(value = "/auto", produces = "application/json; charset=utf-8")
  @ResponseBody
  public Lol automaticSerialization() {

    Lol lol = new Lol();
    lol.a = UUID.randomUUID().toString();
    lol.b = System.currentTimeMillis();

    return lol;
  }

  @RequestMapping(value = "/manual", produces = "application/json; charset=utf-8")
  @ResponseBody
  public String manualSerialization() throws JsonProcessingException {

    Lol lol = new Lol();
    lol.a = UUID.randomUUID().toString();
    lol.b = System.currentTimeMillis();

    return mapper.writeValueAsString(lol);
  }

  public static class Lol {

    String a;
    long b;

    public void setA(String a) {
      this.a = a;
    }

    public void setB(long b) {
      this.b = b;
    }

    public String getA() {
      return a;
    }

    public long getB() {
      return b;
    }
  }

}

编辑: 自动序列化的痕迹: Trace of automatic serialization

手动序列化的痕迹: Trace of manual serialization

最佳答案

我唯一的想法是 Spring 的默认 ObjectMapper 的配置与您在基准测试中使用的配置略有不同。就像评论中提到的那样,如果让 Spring 自动处理映射,您可能会看到一些开销,但它的影响不应超过百分之几。

为了确保比较公平,请将此 bean 定义添加到您的配置中:

@Bean
@Primary
ObjectMapper objectMapper() {
    return new ObjectMapper(new JsonFactory());
}

并将 ObjectMapper mapper = new ObjectMapper(new JsonFactory()); 替换为 Autowiring 字段:

@Autowired
ObjectMapper mapper;

并查看基准测试是否返回相同的值。

编辑

我想亲自验证这一点,所以我编写了一个 JMeter 计划,并执行每个端点 5kk 次,并有 1 分钟的预热时间。结果符合预期,方法之间没有重大差异:

Label,# Samples,Average,Min,Max,Std. Dev.,Error %,Throughput,KB/sec,Avg. Bytes
Auto Request,5000000,2,0,108,5.88,0.00%,15577.3,3088.08,203.0
Manual Request,5000000,2,0,149,5.99,0.00%,15660.2,2813.94,184.0

需要注意的重要一点是吞吐量差异 - 自动的 15577.3 与手动的 15660.2。

Here's my JMeter test plan ,如果你想自己测试一下,我是在端口 8081 上运行的。如果有时间,我会尝试另一个基准测试框架,也许是 Gadling。

关于spring - 为什么Spring MVC json序列化比手动调用jackson慢10倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38422716/

相关文章:

Spring 启动2.0.0.M6 : Show all metrics with one request

spring - JPA @Entity 中的 Bean 注入(inject)

java - Spring Rest Controller 异常处理

html - 为什么尝试使用 SSE 时 DeferredResult 在 setResult() 上结束

java - 如何防止Spring创建一个刚刚扩展的 "abstract"泛型类型存储库?

java - 在 servlet 多部分发布期间无法访问 Spring Security 信息

java - Intellij 不更新 spring.datasource.url

PHP:将列表插入数据库的有效方法

sql-server - 聚集索引中间叶之间的顺序遍历是如何使用的?

c++ - 是否在 C++ 11 的编译时或运行时自动推断类型?