Почему сериализация Spring MVC json 10x медленнее, чем вызов jackson вручную?

использование apachebench с параметрами" ab-k-c 50-N 1000000 " (50 параллельных потоков) показывает разницу в производительности 10x между следующими 2 методами (ручная и управляемая весной сериализация). Возможно ли достичь такой же производительности с помощью конфигурации весенней сериализации?

Я запускаю тест на Windows 7, JDK8, i7-6700. Встроенный котяра, С откат или причал тоже. Похожий WildFly 10 JAX-RS пример производительности приложений дает аналогичные результаты, как ручной spring one, поэтому я не вижу причин, почему Spring automatic mode должен быть настолько медленным.

полный исходный код:

@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

1 ответов


единственная идея, которая у меня есть, это то, что весна по умолчанию ObjectMapper настроен немного иначе, чем тот, который вы используете в тесте. Как и в комментариях, вы, вероятно, увидите немного накладных расходов, если позволите Spring обрабатывать отображение автоматически, но это не должно иметь больше, чем несколько процентов воздействия.

чтобы убедиться, что сравнение справедливо, добавьте это определение bean в свою конфигурацию:

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

и заменить ObjectMapper mapper = new ObjectMapper(new JsonFactory()); С autowired поле:

@Autowired
ObjectMapper mapper;

и посмотрите, возвращают ли бенчмарки одно и то же значение.

редактировать

Я хотел проверить это для myselt, поэтому я написал план 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.

вот мой план испытаний JMeter, если вы хотите проверить это сами, я работал на порту 8081. Если я найду время, я попробую другую систему бенчмаркинга, возможно, Гатлинга.