4

我在 github 上有一个 json 库https://github.com/jillesvangurp/jsonj

这个库有一个基于 json simple 的解析器,它使用一个处理程序类来完成创建我的库中的 JsonObject、JsonArray 和 JsonPrimitive 实例的所有工作。

我看到人们发布了各种基准测试,表明杰克逊解析器在性能方面与它一样好,而简单的 json 是较慢的选项之一。所以,为了看看我是否可以提高性能,我创建了一个替代解析器,它使用杰克逊流 API 并调用我用于原始解析器的相同处理程序。从功能的角度来看,这很好用,而且非常简单。

您可以在这里找到相关的类(JsonHandler、JsonParser 和 JsonParserNg):https ://github.com/jillesvangurp/jsonj/tree/master/src/main/java/com/github/jsonj/tools

但是,我没有看到我运行的各种测试有任何改进。

所以,我的问题是:我应该看到任何改进吗?如果是,为什么?在我看来,至少在流 API 模式下,两个库的性能相似。

我会对其他人的经验非常感兴趣。

4

1 回答 1

12

不久前,我写了“关于 Java JSON 处理的正确性能测试”,列举了我在性能基准测试中看到的常见问题。有很多相对简单的方法可以搞乱比较。我假设你没有犯任何提到的错误,但值得一提。特别是关于使用原始输入的部分:很少有真正的 JSON 数据来自的情况String——所以一定要使用InputStream/ OutputStream(或字节数组)。

要注意的第二件事是,如果您使用树模型(如JsonObject),您已经添加了许多可能避免的开销:您正在构建一个Map/List结构,它使用 POJO 将使用的 3 倍内存;并且操作速度较慢。在这种情况下,实际的解析/生成开销通常是少数组件。有时树样式处理是有意义的,这是可以接受的开销。

因此,如果性能很重要,通常是:

  1. 使用流式 API 构建您自己的对象——而不是内存中的树,或者
  2. 使用与 POJO 的数据绑定。这可以接近 (1) 的速度

两者都比构建树(在某种程度上,序列化)更快。出于某种原因,许多开发人员以某种方式认为处理树表示与处理数据一样有效——事实并非如此,并且可以在https://github.com/eishay/jvm-serializers等基准测试中看到

我没有通过链接看到杰克逊相关的代码,所以我假设它按预期工作。要寻找的主要事情(wrt性能问题)实际上是:

  1. 总是关闭JsonParserJsonGenerator(需要一些回收)和
  2. 重用JsonFactory和/或ObjectMapper实例:它们是线程安全的,通过这些对象重用某些组件(符号表、序列化程序)。
  3. 如前所述,如果可能,请始终使用大多数原始输入/输出目标 ( InputStream, OutputStream)。
于 2013-04-21T19:48:14.003 回答