Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] 对于JavaBean的序列化速度比Fastjson1要慢 #609

Closed
xinhochen opened this issue Aug 3, 2022 · 8 comments
Closed

[BUG] 对于JavaBean的序列化速度比Fastjson1要慢 #609

xinhochen opened this issue Aug 3, 2022 · 8 comments
Labels
bug Something isn't working
Milestone

Comments

@xinhochen
Copy link

xinhochen commented Aug 3, 2022

问题描述

对于JavaBean的序列化速度比Fastjson1要慢,同时在去掉JSONWriter.Feature.ReferenceDetection之后,会出现OutOfMemoryError。于之对应的,Fastjson1只是偶尔出现OutOfMemoryError。

环境信息

请填写以下信息:

  • OS信息: Win11 6Core 2.90GHz 16GB
  • JDK信息: Temurin - 11.0.14.1
  • 版本信息:Fastjson 2.0.10 & Fastjson 1.2.80
  • JVM参数:-Xms128m -Xmx128m

重现步骤

https://gist.github.com/xinhochen/36f1d0cce97ae765aa9fa127833f2166

期待的正确结果

Fastjson2的序列化吞吐量和耗时优于Fastjson1

相关日志输出

Benchmark Mode Cnt Score Error Units
BenchmarkJSON.fastJSON1ArrayDeThroughput thrpt 5 16.857 ± 0.118 ops/s
BenchmarkJSON.fastJSON2ArrayDeThroughput thrpt 5 29.403 ± 0.172 ops/s
BenchmarkJSON.fastJSON1ArraySeThroughput thrpt 5 16.060 ± 0.518 ops/s
BenchmarkJSON.fastJSON2ArraySeThroughput thrpt 5 OOM ops/s
BenchmarkJSON.fastJSON1ObjDeThroughput thrpt 5 50.981 ± 1.420 ops/s
BenchmarkJSON.fastJSON2ObjDeThroughput thrpt 5 53.947 ± 0.178 ops/s
BenchmarkJSON.fastJSON1ObjSeThroughput thrpt 5 49.275 ± 0.164 ops/s
BenchmarkJSON.fastJSON2ObjSeThroughput thrpt 5 17.894 ± 0.070 ops/s
BenchmarkJSON.fastJSON1ArrayDeTime avgt 5 55.277 ± 0.885 ms/op
BenchmarkJSON.fastJSON2ArrayDeTime avgt 5 36.688 ± 0.687 ms/op
BenchmarkJSON.fastJSON1ArraySeTime avgt 5 61.726 ± 2.049 ms/op
BenchmarkJSON.fastJSON2ArraySeTime avgt 5 69.249 ± 3.040 ms/op
BenchmarkJSON.fastJSON1ObjDeTime avgt 5 19.844 ± 0.372 ms/op
BenchmarkJSON.fastJSON2ObjDeTime avgt 5 18.643 ± 0.042 ms/op
BenchmarkJSON.fastJSON1ObjSeTime avgt 5 22.432 ± 0.037 ms/op
BenchmarkJSON.fastJSON2ObjSeTime avgt 5 56.034 ± 0.181 ms/op

附加信息

@xinhochen xinhochen added the bug Something isn't working label Aug 3, 2022
@xinhochen xinhochen changed the title [BUG] [BUG] 对于JavaBean的序列化速度比Fastjson1要慢 Aug 3, 2022
wenshao added a commit that referenced this issue Aug 3, 2022
@wenshao
Copy link
Member

wenshao commented Aug 3, 2022

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.11-SNAPSHOT/
问题已经修复,请用2.0.11-SNAPSHOT版本验证,2.0.11版本预计在8月7日发布

Benchmark                             Mode  Cnt    Score    Error  Units
Issue609.fastJSON1ArrayDeThroughput  thrpt    5   39.779 ±  5.517  ops/s
Issue609.fastJSON2ArrayDeThroughput  thrpt    5   68.184 ±  5.387  ops/s

Issue609.fastJSON1ArraySeThroughput  thrpt    5   42.854 ±  1.831  ops/s
Issue609.fastJSON2ArraySeThroughput  thrpt    5   56.745 ±  0.564  ops/s


Issue609.fastJSON1ObjDeThroughput    thrpt    5   68.175 ±  0.566  ops/s
Issue609.fastJSON2ObjDeThroughput    thrpt    5  100.525 ±  1.874  ops/s

Issue609.fastJSON1ObjSeThroughput    thrpt    5   62.280 ±  0.869  ops/s
Issue609.fastJSON2ObjSeThroughput    thrpt    5   92.590 ±  2.127  ops/s

Issue609.fastJSON1ArrayDeTime         avgt    5   29.628 ± 12.199  ms/op
Issue609.fastJSON2ArrayDeTime         avgt    5   15.280 ±  0.636  ms/op

Issue609.fastJSON2ArraySeTime         avgt    5   17.026 ±  0.227  ms/op
Issue609.fastJSON1ArraySeTime         avgt    5   23.259 ±  0.866  ms/op

Issue609.fastJSON1ObjDeTime           avgt    5   15.204 ±  0.225  ms/op
Issue609.fastJSON2ObjDeTime           avgt    5    9.907 ±  0.066  ms/op

Issue609.fastJSON1ObjSeTime           avgt    5   16.105 ±  0.277  ms/op
Issue609.fastJSON2ObjSeTime           avgt    5   10.677 ±  0.117  ms/op

@wenshao wenshao added this to the 2.0.11 milestone Aug 3, 2022
@xinhochen
Copy link
Author

xinhochen commented Aug 4, 2022

刚刚用2.0.11-SNAPSHOT又跑了两次,还是fastjson1快一些
第一次是fastjson1出了OOM:

Benchmark                                  Mode  Cnt   Score    Error  Units
BenchmarkJSON.fastJSON1ArrayDeThroughput  thrpt    5  16.178 ±  0.091  ops/s
BenchmarkJSON.fastJSON2ArrayDeThroughput  thrpt    5  26.502 ±  0.181  ops/s

BenchmarkJSON.fastJSON1ArraySeThroughput  thrpt    5  12.312 ±  0.868  ops/s
BenchmarkJSON.fastJSON2ArraySeThroughput  thrpt    5  13.073 ±  0.464  ops/s

BenchmarkJSON.fastJSON1ObjDeThroughput    thrpt    5  38.096 ±  0.162  ops/s
BenchmarkJSON.fastJSON2ObjDeThroughput    thrpt    5  48.042 ±  0.140  ops/s

BenchmarkJSON.fastJSON1ObjSeThroughput    thrpt    5  28.130 ±  0.158  ops/s
BenchmarkJSON.fastJSON2ObjSeThroughput    thrpt    5  17.655 ±  0.046  ops/s <= 吞吐量小于fastjson1

BenchmarkJSON.fastJSON1ArrayDeTime         avgt    5  61.460 ±  0.222  ms/op
BenchmarkJSON.fastJSON2ArrayDeTime         avgt    5  36.497 ±  0.087  ms/op

BenchmarkJSON.fastJSON1ObjDeTime           avgt    5  26.347 ±  0.083  ms/op
BenchmarkJSON.fastJSON2ObjDeTime           avgt    5  21.208 ±  0.083  ms/op

BenchmarkJSON.fastJSON1ObjSeTime           avgt    5  37.991 ±  0.623  ms/op
BenchmarkJSON.fastJSON2ObjSeTime           avgt    5  56.020 ±  0.151  ms/op <= 耗时大于fastjson1

BenchmarkJSON.fastJSON2ArraySeTime         avgt    5  70.058 ± 11.770  ms/op

第二次:

Benchmark                                  Mode  Cnt   Score   Error  Units
BenchmarkJSON.fastJSON1ArrayDeThroughput  thrpt    5  15.587 ± 0.069  ops/s
BenchmarkJSON.fastJSON2ArrayDeThroughput  thrpt    5  26.932 ± 0.277  ops/s

BenchmarkJSON.fastJSON1ArraySeThroughput  thrpt    5  12.038 ± 1.162  ops/s
BenchmarkJSON.fastJSON2ArraySeThroughput  thrpt    5  14.216 ± 0.947  ops/s

BenchmarkJSON.fastJSON1ObjDeThroughput    thrpt    5  38.550 ± 0.139  ops/s
BenchmarkJSON.fastJSON2ObjDeThroughput    thrpt    5  48.215 ± 0.256  ops/s

BenchmarkJSON.fastJSON1ObjSeThroughput    thrpt    5  27.953 ± 0.060  ops/s
BenchmarkJSON.fastJSON2ObjSeThroughput    thrpt    5  17.526 ± 0.054  ops/s <= 吞吐量小于fastjson1

BenchmarkJSON.fastJSON1ArrayDeTime         avgt    5  64.037 ± 0.805  ms/op
BenchmarkJSON.fastJSON2ArrayDeTime         avgt    5  38.977 ± 0.184  ms/op

BenchmarkJSON.fastJSON1ArraySeTime         avgt    5  79.019 ± 6.010  ms/op
BenchmarkJSON.fastJSON2ArraySeTime         avgt    5  71.198 ± 7.717  ms/op

BenchmarkJSON.fastJSON1ObjDeTime           avgt    5  26.214 ± 0.132  ms/op
BenchmarkJSON.fastJSON2ObjDeTime           avgt    5  21.445 ± 0.118  ms/op

BenchmarkJSON.fastJSON1ObjSeTime           avgt    5  34.891 ± 0.135  ms/op
BenchmarkJSON.fastJSON2ObjSeTime           avgt    5  58.859 ± 0.091  ms/op <= 耗时大于fastjson1

@wenshao
Copy link
Member

wenshao commented Aug 4, 2022

能提供下你跑benchmark的环境信息么?比如硬件、内存、JDK版本、JVM参数配置

@xinhochen
Copy link
Author

已经在最开始提供了

@xinhochen
Copy link
Author

我debug了序列化的逻辑,发现最终执行的是ObjectWriterAdpter的write方法

        jsonWriter.startObject();

        if (((features | this.features) & JSONWriter.Feature.WriteClassName.mask) != 0 || jsonWriter.isWriteTypeInfo(object, features)) {
            writeTypeInfo(jsonWriter);
        }

        for (int i = 0, size = fieldWriters.size(); i < size; ++i) {
            FieldWriter fieldWriter = fieldWriters.get(i);
            fieldWriter.write(jsonWriter, object);
        }

        jsonWriter.endObject();

其中的FieldWriter的write方法在本次benchmark中对应FieldWriterStringMethod和FieldWriterInt32,对应的write方法要考虑UTF8,我猜测可能这是慢的原因之一。
另外,FieldWriterInt32的writeInt32方法中,我发现两点:

  1. utf8ValueCache是一个成员变量,对于每一个对象第一次序列化int32值时都要初始化。这里是否可以修改为静态变量,减少内存占用和重复初始化的开销
  2. 对于nameWithColonUTF8,有一个Arrays.copyOf,做了一个深拷贝存储在original中。我觉得这个操作是多余的,因为后续又把这个orignal通过Arrays.copyOf深拷贝到bytes中了。后续的操作都是针对bytes的,这里的orginal我实在是找不到它存在的原因。

@wenshao
Copy link
Member

wenshao commented Aug 7, 2022

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.12-SNAPSHOT/
2.0.12-SNAPSHOT版本修复了问题,序列化之前没有针对中文场景做优化,测试的都是ascii场景。

@xinhochen
Copy link
Author

👍

wenshao added a commit that referenced this issue Aug 12, 2022
@wenshao
Copy link
Member

wenshao commented Aug 20, 2022

https://github.com/alibaba/fastjson2/releases/tag/2.0.12
问题已修复,请用新版本

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants