json-iterator / java

jsoniter (json-iterator) is fast and flexible JSON parser available in Java and Go
http://jsoniter.com/
MIT License
1.51k stars 519 forks source link

In the micro-benchmark test, the jsoniter serialization performance seems to be a bit poor #328

Closed lost22git closed 1 year ago

lost22git commented 1 year ago

image

Test json

{
   "id":-5106534569952410475,
   "firstName":"eOMtThyhVNLWUZNRcBaQKxI",
   "lastName":"yedUsFwdkelQbxeTeQOvaScfqIOOmaa",
   "age":-1188957731,
   "gender":"UNKNOWN",
   "friends":[
      {
         "id":-167885730524958550,
         "firstName":"JxkyvRnL",
         "lastName":"RYtGKbgicZaHCBRQDSx",
         "age":1018954901,
         "gender":"UNKNOWN",
         "friends":[
            {
               "id":4672433029010564658,
               "firstName":"VLhpfQGTMDYpsBZxvfBoeygjb",
               "lastName":"UMaAIKKIkknjWEXJUfPxxQHeWKEJ",
               "age":-39088943,
               "gender":"UNKNOWN",
               "friends":[
                  {
                     "id":null,
                     "firstName":null,
                     "lastName":null,
                     "age":null,
                     "gender":null,
                     "friends":null,
                     "attrs":null
                  },
                  {
                     "id":null,
                     "firstName":null,
                     "lastName":null,
                     "age":null,
                     "gender":null,
                     "friends":null,
                     "attrs":null
                  }
               ],
               "attrs":{
                  "dpHYZGhtgdntugzvvKAXLhM":"LlN",
                  "gNfZBdyFGRajVfJNonEnOinZj":"UfzQhdgLLfDTDGspDb",
                  "QvBQYuxiXXVytGCxzVllpgTJKhRQq":"qszYL"
               }
            }
         ],
         "attrs":{
            "Oxm":"QIn",
            "YdvDhtAsLghPXAgtbprXPZkhnfLTBSX":"sPB",
            "yIvpRgmgQsYEKk":"AAAryjCRhLTuhnTodUewZQqaZErU"
         }
      }
   ],
   "attrs":{
      "aofGvthLoyPLDADYzx":"WoaMAzEEplqjJ",
      "jNBgpTmxx":"pIoQM",
      "ODRhfGEfX":"IoTtOmcBeivNUYv"
   }
}

User.java

public class User {
    private Long id;
    private String firstName;
    private String lastName;
    private Integer age;
    private Gender gender;
    private Set<User> friends;
    private Map<String, String> attrs;

    User() {

    }

    User(Long id,
         String firstName,
         String lastName,
         Integer age,
         Gender gender,
         Set<User> friends,
         Map<String, String> attrs) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.gender = gender;
        this.friends = friends;
        this.attrs = attrs;
    }

    public enum Gender {
        MALE, FEMALE, UNKNOWN
    }

    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", firstName='" + firstName + '\'' +
            ", lastName='" + lastName + '\'' +
            ", age=" + age +
            ", gender=" + gender +
            ", friends=" + friends +
            ", attrs=" + attrs +
            '}';
    }

    // ----------- getters / setters ...
}

Main.java


@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 3, time = 5)
@Measurement(iterations = 5, time = 5)
@Fork(2)
public class Main {

    static ObjectMapper JACKSON;

    static Gson GSON;

    static JsonAdapter<User> MOSHI;

    static User USER;
    static String JSON;

    static {
        var params = new EasyRandomParameters()
            .objectPoolSize(100)
            .randomizationDepth(3)
            .collectionSizeRange(1, 5);
        var easyRandom = new EasyRandom(params);
        USER = easyRandom.nextObject(User.class);

        JACKSON = new ObjectMapper()
            .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

       GSON = new Gson();

        MOSHI = new Moshi.Builder().build()
            .adapter(User.class);

        try {
            JSON = JACKSON.writeValueAsString(USER);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        System.out.println("JSON: \n" + JSON);
    }

    @Benchmark
    public void jackson_serialize(Blackhole blackhole) throws JsonProcessingException {
        var json = JACKSON.writeValueAsString(USER);
        blackhole.consume(json);
    }

    @Benchmark
    public void jackson_deserialize(Blackhole blackhole) throws JsonProcessingException {
        var user = JACKSON.readValue(JSON, User.class);
        blackhole.consume(user);
    }

    @Benchmark
    public void jsoniter_serialize(Blackhole blackhole) {
        var json = JsonStream.serialize(USER);
        blackhole.consume(json);
    }

    @Benchmark
    public void jsoniter_deserialize(Blackhole blackhole) {
        var user = JsonIterator.deserialize(JSON, User.class);
        blackhole.consume(user);
    }

    @Benchmark
    public void fastjson_serialize(Blackhole blackhole) {
        var json = com.alibaba.fastjson.JSON.toJSONString(USER);
        blackhole.consume(json);
    }

    @Benchmark
    public void fastjson_deserialize(Blackhole blackhole) {
        var user = com.alibaba.fastjson.JSON.parseObject(JSON, User.class);
        blackhole.consume(user);
    }

    @Benchmark
    public void moshi_serialize(Blackhole blackhole) {
        var json = MOSHI.toJson(USER);
        blackhole.consume(json);
    }

    @Benchmark
    public void moshi_deserialize(Blackhole blackhole) throws IOException {
        var user = MOSHI.fromJson(JSON);
        blackhole.consume(user);
    }

    public static void main(String[] args) throws RunnerException {
        final Options options =
            new OptionsBuilder().include(Main.class.getName()).build();

        new Runner(options).run();
    }

}