3 つを比較した結果、この JSON ライブラリが最も使いやすいことがわかりました。

リリース: 2023-07-26 17:12:06
転載
1811 人が閲覧しました

この記事では、JMH を使用して、Java のいくつかの一般的な JSON 解析ライブラリのパフォーマンスをテストします。インターネット上で他の人が特定のライブラリのパフォーマンスがいかに優れているかを述べ、他のライブラリを押しつぶしているのを見るたびに。しかし、聞くよりも見る方が優れており、自分で試したものだけが最も信頼できます。

JSON は、Web 開発とサーバー開発の両方で非常に一般的なデータ送信形式です。一般に、JSON 解析構築のパフォーマンスについてあまり心配する必要はありません。比較的高いパフォーマンス要件が必要なシステムではない限り。

現在、Java にはオープン ソースの

JSON クラス ライブラリが多数あります。以下では、パフォーマンス テストと比較のために一般的に使用される 4 つの JSON ライブラリを取り上げ、以下に基づいているかどうかを分析します。テスト結果 実際のアプリケーション シナリオに応じて、最適な JSON ライブラリを選択します。

4 つの JSON クラス ライブラリは、

Gson、FastJson、Jackson、Json-lib です。

簡単な紹介

さまざまな側面から考慮して適切な JSON ライブラリを選択してください:

  • String JSON パフォーマンスへの解析

  • JavaBean パフォーマンスへの文字列解析

  • JavaBean 構築 JSON パフォーマンス

  • コレクション構築 JSON のパフォーマンス

  • 使いやすさ

4 つのクラス ライブラリのアイデンティティの背景を簡単に紹介しましょう。

#Gson

# プロジェクトアドレス: https://github.com/google/gson

Gson は、現在最も汎用性の高い Json 解析アーティファクトです。Gson は元々、Google の内部ニーズに応えて Google によって開発されました。しかし、最初のバージョンが 2008 年 5 月に公開されて以来、多くの企業やユーザーが使用しています。適用する。

Gson のアプリケーションは、主に toJson と fromJson という 2 つの変換関数で構成されています。依存関係はなく、追加の jar も必要ありません。JDK 上で直接実行できます。

この種のオブジェクト変換を使用する前に、JSON 文字列を対応するオブジェクトに正常に変換する前に、オブジェクト タイプとそのメンバーを作成する必要があります。クラスに get メソッドと set メソッドがある限り、Gson は複雑なタイプの json から Bean へ、または Bean から json へ完全に変換できます。これは JSON 解析の成果物です。

#FastJson

プロジェクトアドレス: https://github.com/alibaba/fastjson

##Fastjson は、Alibaba によって開発された、Java 言語で書かれた高性能 JSON プロセッサです。依存関係や追加の jar は必要なく、JDK 上で直接実行できます。

FastJson では、複雑な型の Bean を Json に変換するときに問題が発生します。参照型が表示されて Json 変換エラーが発生する可能性があり、参照を指定する必要があります。 FastJson は独自のアルゴリズムを使用して解析速度を極限まで高め、あらゆる json ライブラリを上回ります。

ジャクソン

プロジェクトアドレス: https://github.com/FasterXML/jackson

#Jackson は、現在、json をシリアル化および逆シリアル化するために広く使用されている Java オープン ソース フレームワークです。

Jackson コミュニティは比較的活発で、更新速度も比較的速いです。Github の統計によると、Jackson は最も人気のある json パーサーの 1 つであり、Spring MVC のデフォルトの json パーサーです。 . ジャクソンです。

Jackson には多くの利点があります:

  • Jackson は依存する jar パッケージが少なく、シンプルで使いやすいです。

  • Gson などの他の Java json フレームワークと比較して、Jackson は大きな json ファイルをより速く解析します。

  • Jackson は実行時に消費するメモリが少なく、パフォーマンスが向上します

  • Jackson は柔軟性がありますAPI は簡単に拡張およびカスタマイズできます。

#最新バージョンは 2.9.4 です。Jackson のコア モジュールは 3 つの部分で構成されています:

  • ##jackson-core コア パッケージは、JsonPaser や JsonGenerator などの「ストリーム モード」解析に基づいた関連 API を提供します。 Jackson の内部実装は、高性能ストリーミング API の JsonGenerator と JsonParser を通じて json を生成および解析します。

  • #jackson-annotations アノテーション パッケージ、標準のアノテーション関数を提供します;

  • #jackson-databind データバインディング パッケージは、「オブジェクト バインディング」解析 (ObjectMapper) および「ツリー モデル」解析に基づく関連 API (JsonNode) を提供します。「オブジェクト バインディング」解析および「ツリー モデル」解析に基づく API 「ストリーム モード」に基づく API 依存関係「解析中。

Json-lib

プロジェクトアドレス: http://json-lib.sourceforge.net/index.html

json-lib は、最も古く、最も広く使用されている json 解析ツールです。json-lib の欠点は、多くのサードパーティ パッケージに依存していることです。複雑な型変換の場合、json -lib には json を Bean に変換する際の欠陥がまだあります。たとえば、別のクラスのリストまたはマップ コレクションがクラス内にある場合、json-lib による json から Bean への変換で問題が発生します。 json-lib は、機能とパフォーマンスの点で現在のインターネットのニーズを満たすことができません。

パフォーマンス テストの作成

次に、これら 4 つのライブラリのパフォーマンス テスト コードの作成を開始します。

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图片的方法。

执行后的结果图:

3 つを比較した結果、この 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() {
    }
}
ログイン後にコピー

执行后的结果图:

3 つを比較した結果、この JSON ライブラリが最も使いやすいことがわかりました。从上面的测试结果可以看出,反序列化的时候,Gson、Jackson和FastJson区别不大,性能都很优异,而那个Json-lib还是来继续搞笑的。

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

以上が3 つを比較した結果、この JSON ライブラリが最も使いやすいことがわかりました。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:Java学习指南
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート