> Java > java지도 시간 > 본문

세 가지를 비교한 결과 이 ​​JSON 라이브러리가 사용하기에 가장 적합하다는 것을 알았습니다.

풀어 주다: 2023-07-26 17:12:06
앞으로
1810명이 탐색했습니다.

이 기사에서는 JMH를 사용하여 Java에서 몇 가지 일반적인 JSON 구문 분석 라이브러리의 성능을 테스트합니다. 인터넷에서 다른 사람들이 특정 라이브러리의 성능이 얼마나 좋은지 말하고 다른 라이브러리를 무너뜨리는 것을 볼 때마다. 그러나 보는 것이 듣는 것보다 낫습니다. 오직 스스로 시험해 본 것이 가장 신뢰할 수 있습니다.

JSON은 웹 개발과 서버 개발 모두에서 매우 일반적인 데이터 전송 형식입니다. 일반적으로 상대적으로 성능이 뛰어난 시스템이 아닌 이상 JSON 구문 분석 구성의 성능에 크게 신경 쓸 필요는 없습니다. 요구 사항.

현재 Java용 오픈 소스

JSON 클래스 라이브러리가 많이 있습니다. 아래에서는 성능 테스트 및 비교를 위해 일반적으로 사용되는 4개의 JSON 라이브러리를 선택합니다. 동시에 테스트 결과를 바탕으로 가장 많이 선택하는 방법을 분석합니다. 실제 애플리케이션 시나리오에 따라 적절한 JSON 라이브러리.

4개의 JSON 라이브러리는

Gson, FastJson, Jackson, Json-lib입니다.

간단한 소개

다양한 측면에서 고려할 적절한 JSON 라이브러리를 선택하세요.

  • 문자열 구문 분석을 JSON 성능으로

  • 문자열 구문 분석을 JavaBean 성능으로

  • JavaBean 구축 JSON 성능

  • 컬렉션 구성 JSON 성능

  • 사용 편의성

먼저 4개 학급도서관의 아이덴티티 배경을 간단히 소개하겠습니다.

Gson

프로젝트 주소: https://github.com/google/gson

Gson은 원래 Google의 내부 요구 사항을 충족하기 위해 개발된 가장 다재다능한 Json 구문 분석 아티팩트입니다. Google이 자체 개발했지만, 2008년 5월 첫 번째 버전이 공개된 이후 많은 기업이나 사용자가 사용해 왔습니다.

Gson의 애플리케이션은 주로 toJson과 fromJson의 두 가지 변환 기능으로 구성되어 있으며 종속성이 없으며 JDK에서 직접 실행할 수 있습니다.

이러한 개체 변환을 사용하기 전에 개체 유형과 해당 멤버를 생성해야 JSON 문자열을 해당 개체로 성공적으로 변환할 수 있습니다. 클래스에 get 및 set 메소드가 있는 한 Gson은 복잡한 유형의 json을 bean으로 또는 bean을 json으로 완전히 변환할 수 있습니다.

FastJson

프로젝트 주소: https://github.com/alibaba/fastjson

Fastjson은 Alibaba에서 개발한 Java 언어로 작성된 고성능 JSON 프로세서입니다. 종속성이 없고 추가 jar이 필요하지 않으며 JDK에서 직접 실행할 수 있습니다.

FastJson은 복잡한 유형의 Bean을 Json으로 변환할 때 몇 가지 문제가 있습니다. 참조 유형이 나타나 Json 변환 오류가 발생할 수 있으며 참조를 지정해야 합니다. FastJson은 독창적인 알고리즘을 사용하여 모든 json 라이브러리를 능가하는 구문 분석 속도를 극도로 높입니다.

Jackson

프로젝트 주소: https://github.com/FasterXML/jackson

Jackson은 현재 json 직렬화 및 역직렬화에 널리 사용되는 Java 오픈 소스 프레임워크입니다.

Jackson 커뮤니티는 상대적으로 활발하고 업데이트 속도도 상대적으로 빠릅니다. Github의 통계에 따르면 Jackson은 Spring MVC의 기본 json 파서 중 하나입니다.

Jackson에는 많은 장점이 있습니다.

  • Jackson은 더 적은 수의 jar 패키지에 의존하고 간단하고 사용하기 쉽습니다.

  • Gson과 같은 다른 Java json 프레임워크와 비교하여 Jackson은 대용량 json 파일을 더 빠르게 구문 분석합니다.

  • Jackson은 실행 시 메모리를 덜 차지하며 성능은 더 좋습니다

  • Jackson은 쉽게 확장하고 사용자 정의할 수 있는 유연한 API를 제공합니다.

최신 버전은 2.9.4입니다. Jackson의 핵심 모듈은 세 부분으로 구성됩니다.

  • jackson-core 코어 패키지는 JsonPaser 및 JsonGenerator. Jackson의 내부 구현에서는 고성능 스트리밍 API의 JsonGenerator 및 JsonParser를 사용하여 json을 생성하고 구문 분석합니다.

  • jackson-annotations 주석 패키지, 표준 주석 기능 제공

  • jackson-databind 데이터 바인딩 패키지, "객체 바인딩" 구문 분석을 기반으로 하는 관련 API(ObjectMapper) 및 "트리 모델" 제공 관련 API(JsonNode), "객체 바인딩" 구문 분석을 기반으로 하는 API 및 "트리 모델" 구문 분석 API는 "스트림 모드" 구문 분석을 기반으로 하는 API에 의존합니다.

Json-lib

프로젝트 주소: http://json-lib.sourceforge.net/index.html

json-lib는 가장 초기이자 가장 널리 사용되는 json 구문 분석 도구입니다. json-lib의 단점은 실제로 많은 타사 패키지에 의존한다는 것입니다. 복잡한 유형을 변환하기 위해 json-lib는 json을 빈으로 변환하는 데 여전히 결함이 있습니다. 예를 들어 한 클래스에는 목록이나 맵이 있습니다. 다른 클래스의 컬렉션인 json -lib는 json에서 bean으로 변환할 때 문제를 일으킬 것입니다. json-lib는 기능과 성능 측면에서 현재 인터넷 요구 사항을 충족할 수 없습니다.

성능 테스트 작성

다음으로, 이 네 가지 라이브러리에 대한 성능 테스트 코드 작성을 시작하세요.

Maven 종속성 추가

물론 첫 번째 단계는 4개 라이브러리의 Maven 종속성을 추가하는 것입니다. 공평하게 말하면 저는 최신 버전을 모두 사용합니다.

<!-- Json libs-->
<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.46</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.4</version>
</dependency>
로그인 후 복사

4개의 라이브러리

FastJsonUtil .java

public class FastJsonUtil {
    public static String bean2Json(Object obj) {
        return JSON.toJSONString(obj);
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        return JSON.parseObject(jsonStr, objClass);
    }
}
로그인 후 복사

GsonUtil.java

public class GsonUtil {
    private static Gson gson = new GsonBuilder().create();

    public static String bean2Json(Object obj) {
        return gson.toJson(obj);
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        return gson.fromJson(jsonStr, objClass);
    }

    public static String jsonFormatter(String uglyJsonStr) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonParser jp = new JsonParser();
        JsonElement je = jp.parse(uglyJsonStr);
        return gson.toJson(je);
    }
}
로그인 후 복사

JacksonUtil.java

public class JacksonUtil {
    private static ObjectMapper mapper = new ObjectMapper();

    public static String bean2Json(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        try {
            return mapper.readValue(jsonStr, objClass);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
로그인 후 복사

JsonLibUtil.java

public class JsonLibUtil {

    public static String bean2Json(Object obj) {
        JSONObject jsonObject = JSONObject.fromObject(obj);
        return jsonObject.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        return (T) JSONObject.toBean(JSONObject.fromObject(jsonStr), objClass);
    }
}
로그인 후 복사

准备Model类

这里我写一个简单的Person类,同时属性有Date、List、Map和自定义的类FullName,最大程度模拟真实场景。

public class Person {
    private String name;
    private FullName fullName;
    private int age;
    private Date birthday;
    private List<String> hobbies;
    private Map<String, String> clothes;
    private List<Person> friends;
    // getter/setter省略
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder("Person [name=" + name + ", fullName=" + fullName + ", age="
                + age + ", birthday=" + birthday + ", hobbies=" + hobbies
                + ", clothes=" + clothes + "]
");
        if (friends != null) {
            str.append("Friends:
");
            for (Person f : friends) {
                str.append("	").append(f);
            }
        }
        return str.toString();
    }

}
로그인 후 복사

public class FullName {
    private String firstName;
    private String middleName;
    private String lastName;

    public FullName() {
    }
    public FullName(String firstName, String middleName, String lastName) {
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
    }
    // 省略getter和setter
    @Override
    public String toString() {
        return "[firstName=" + firstName + ", middleName="
                + middleName + ", lastName=" + lastName + "]";
    }
}
로그인 후 복사

JSON序列化性能基准测试

@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonSerializeBenchmark {
    /**
     * 序列化次数参数
     */
    @Param({"1000", "10000", "100000"})
    private int count;

    private Person p;

    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
                .include(JsonSerializeBenchmark.class.getSimpleName())
                .forks(1)
                .warmupIterations(0)
                .build();
        Collection<RunResult> results =  new Runner(opt).run();
        ResultExporter.exportResult("JSON序列化性能", results, "count", "秒");
    }

    @Benchmark
    public void JsonLib() {
        for (int i = 0; i < count; i++) {
            JsonLibUtil.bean2Json(p);
        }
    }

    @Benchmark
    public void Gson() {
        for (int i = 0; i < count; i++) {
            GsonUtil.bean2Json(p);
        }
    }

    @Benchmark
    public void FastJson() {
        for (int i = 0; i < count; i++) {
            FastJsonUtil.bean2Json(p);
        }
    }

    @Benchmark
    public void Jackson() {
        for (int i = 0; i < count; i++) {
            JacksonUtil.bean2Json(p);
        }
    }

    @Setup
    public void prepare() {
        List<Person> friends=new ArrayList<Person>();
        friends.add(createAPerson("小明",null));
        friends.add(createAPerson("Tony",null));
        friends.add(createAPerson("陈小二",null));
        p=createAPerson("邵同学",friends);
    }

    @TearDown
    public void shutdown() {
    }

    private Person createAPerson(String name,List<Person> friends) {
        Person newPerson=new Person();
        newPerson.setName(name);
        newPerson.setFullName(new FullName("zjj_first", "zjj_middle", "zjj_last"));
        newPerson.setAge(24);
        List<String> hobbies=new ArrayList<String>();
        hobbies.add("篮球");
        hobbies.add("游泳");
        hobbies.add("coding");
        newPerson.setHobbies(hobbies);
        Map<String,String> clothes=new HashMap<String, String>();
        clothes.put("coat", "Nike");
        clothes.put("trousers", "adidas");
        clothes.put("shoes", "安踏");
        newPerson.setClothes(clothes);
        newPerson.setFriends(friends);
        return newPerson;
    }
}
로그인 후 복사

说明一下,上面的代码中

ResultExporter.exportResult("JSON序列化性能", results, "count", "秒");
로그인 후 복사

这个是我自己编写的将性能测试报告数据填充至Echarts图,然后导出png图片的方法。

执行后的结果图:

세 가지를 비교한 결과 이 ​​JSON 라이브러리가 사용하기에 가장 적합하다는 것을 알았습니다.从上面的测试结果可以看出,序列化次数比较小的时候,Gson性能最好,当不断增加的时候到了100000,Gson明细弱于Jackson和FastJson, 这时候FastJson性能是真的牛,另外还可以看到不管数量少还是多,Jackson一直表现优异。而那个Json-lib简直就是来搞笑的。^_^

JSON反序列化性能基准测试

@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonDeserializeBenchmark {
    /**
     * 反序列化次数参数
     */
    @Param({"1000", "10000", "100000"})
    private int count;

    private String jsonStr;

    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
                .include(JsonDeserializeBenchmark.class.getSimpleName())
                .forks(1)
                .warmupIterations(0)
                .build();
        Collection<RunResult> results =  new Runner(opt).run();
        ResultExporter.exportResult("JSON反序列化性能", results, "count", "秒");
    }

    @Benchmark
    public void JsonLib() {
        for (int i = 0; i < count; i++) {
            JsonLibUtil.json2Bean(jsonStr, Person.class);
        }
    }

    @Benchmark
    public void Gson() {
        for (int i = 0; i < count; i++) {
            GsonUtil.json2Bean(jsonStr, Person.class);
        }
    }

    @Benchmark
    public void FastJson() {
        for (int i = 0; i < count; i++) {
            FastJsonUtil.json2Bean(jsonStr, Person.class);
        }
    }

    @Benchmark
    public void Jackson() {
        for (int i = 0; i < count; i++) {
            JacksonUtil.json2Bean(jsonStr, Person.class);
        }
    }

    @Setup
    public void prepare() {
        jsonStr="{"name":"邵同学","fullName":{"firstName":"zjj_first","middleName":"zjj_middle","lastName":"zjj_last"},"age":24,"birthday":null,"hobbies":["篮球","游泳","coding"],"clothes":{"shoes":"安踏","trousers":"adidas","coat":"Nike"},"friends":[{"name":"小明","fullName":{"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age":24,"birthday":null,"hobbies":["篮球","游泳","coding"],"clothes":{"shoes":"安踏","trousers":"adidas","coat":"Nike"},"friends":null},{"name":"Tony","fullName":{"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age":24,"birthday":null,"hobbies":["篮球","游泳","coding"],"clothes":{"shoes":"安踏","trousers":"adidas","coat":"Nike"},"friends":null},{"name":"陈小二","fullName":{"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age":24,"birthday":null,"hobbies":["篮球","游泳","coding"],"clothes":{"shoes":"安踏","trousers":"adidas","coat":"Nike"},"friends":null}]}";
    }

    @TearDown
    public void shutdown() {
    }
}
로그인 후 복사

执行后的结果图:

세 가지를 비교한 결과 이 ​​JSON 라이브러리가 사용하기에 가장 적합하다는 것을 알았습니다.从上面的测试结果可以看出,反序列化的时候,Gson、Jackson和FastJson区别不大,性能都很优异,而那个Json-lib还是来继续搞笑的。

以上就是几种几种主流JSON库的基本介绍,希望能对你有所帮助!

위 내용은 세 가지를 비교한 결과 이 ​​JSON 라이브러리가 사용하기에 가장 적합하다는 것을 알았습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:Java学习指南
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿