在Jackson中将4Mb的JSON转换为java对象需要1500ms

时间:2015-11-20 13:17:10

标签: java json performance jackson

在我的应用中,一个实体建模如下:

class Node{
     private String parentNodeId;
     private Node parentNode;
     // other properties and their `getters` and setters
}

因为我使用NoSql DB的非规范化形式。每个节点都有它的父节点引用。这种方式在DB中我有540条记录,大约是4Mb的JSON数据。从DB获取这些记录不需要花费太多时间(70ms)。但是将那些从JSON反序列化到Java对象的时间接近1500毫秒。为了完成它而要求所有人花费2000毫秒。进行转换的代码如下

List<String> records = DB.get("some criteria");
List<Node> results = Lists.newArrayList();
for(String entity : records){
   results.add(convertJSONToObject(entity, Node.class));
}

private <T> T convertJSONToObject(String record, Class<T> entityClass){
      if(StringUtils.isBlank(json)){
         return null;
      }
      ObjectReader reader = MAPPER.reader(objectClass);
      return reader.readValue(json);
}

有没有更好的方法可以缩短转换时间,或者这个速度对于大量数据是可以接受的?

1 个答案:

答案 0 :(得分:1)

由于将Object模型完全保留在内存中以及这些模型的复杂性(可能有大量POJO),文档解析器可能相当重。

首先,值得对反序列化过程进行剖析,以确保它不会像IO一样受到限制,花费大量时间进行反思,或者进行某种线程争用。可能存在一些问题,您可以轻松修复或优化。

其次,通过多线程可以在现代系统上实现大量的性能提升。也许考虑将你的JSON模型分解成碎片并将它们并行反序列化,或者看看杰克逊是否可以选择为你做这个。

如果您要定期要求这些对象并且您的数据有一定的生命周期,您可能需要考虑缓存这些对象并使用一种机制在适当的时间使它们失效或更新。您还应该考虑排除您不会使用的字段。

另一个需要关注的是你是否需要立即反序列化整个对象。我相信Jackson确实有能力提供随机访问,因此,当您等待1500ms进行反序列化时,您可以通过该方法提供临时访问,并简单地反序列化所需的字段。或者,完全接受这种方法 - 为什么反序列化你不需要的东西?

更进一步,如果您正在处理所有对象,您可能需要考虑使用流式解析器。如果这是工作流程的一部分,并且不排除在该过程中分离对象模型,那么这将更适合。

如果你不确定杰克逊的表现,可能值得寻找替代方案,看看他们是否做得更好。在某些情况下,GSON已经证明比Jackson快得多,还存在JSONP和JSON.simple。对您的用例进行基准测试可以让您最好地了解哪些项目最适合您。