FastJson、Jackson、Gson、Hutool,JSON解析哪家强?JMH基准测试来排行

news2024/11/14 18:52:39

首发公众号:【赵侠客】

引言

在前面《释放你九成的带宽和内存:GZIP在解决Redis大Key方面的应用》一文中我使用GZIP算法对JSON格式数据进行了压缩,可以减小88%的空间,文中也提到了目前JSON格式在我们项目中应用的非常广泛几乎无处不在。压缩JSON格式数据可以大大降低我们的存储和带宽成本,我们知道数据格式的转换过程是需要消耗CPU计算资源的,JSON格式数据转换的快慢也会直接影响我们接口响应的快慢,甚至影响我们系统的吞吐量,所以本文针对市面上主流的5种JSON解析工具FastJson、FastJson2、JackSon、Gson、Hutool-JSON使用JAVA基准测试分别对小JSON、中JSON、大JSON的序列化和返序列化共6项指标进行测试,最后给出了测试排行榜,希望最后的排行榜能对您在做JSON工具选型时有一定的帮助。

二、准备工作

2.1 JMH基准测试

平时我们做代码性能测试可能就是在代码执行前通过System.currentTimeMillis()获取一下当前时间,代码执行后再获取一个当前时间,然后两个时间相减得出代码的运行时间,这种测试是非常不准确的,包括获取时间的精度、JIT编译优化导致性能测试结果不稳定、系统当前的负载,包括CPU、内存、磁盘I/O等会影响测试结果、Java虚拟机(JVM)需要一段时间来预热也会影响测试结果。所以为了测试的准确性,本文使用JMH(Java Microbenchmark Harness)进行测试,JMH是由OpenJDK/Oracle维护的Java基准测试工具,它旨在帮助开发人员编写准确的基准测试,以避免常见的基准测试陷阱,并提供可靠的性能测试结果。因为使用的JMH基准测试所以测试结果应该是有说服力的。

添加JMH Maven依赖:

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.36</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.36</version>
</dependency>

JMH测试代码:

@State(Scope.Thread)
public class HelloBenchmark {
    @Benchmark
    public void testMethod() throws InterruptedException {
        Thread.sleep(10);
    }
    @Test
    public void testBenchmark() throws Exception {
        Options options = new OptionsBuilder()
                .include(HelloBenchmark.class.getSimpleName())
                .forks(1) //进程数
                .threads(1) //线程数
                .warmupIterations(1) 
                .measurementIterations(1)
                .mode(Mode.Throughput)
                .build();
        new Runner(options).run();
    }
}

JMH测试结果:

Benchmark   Mode   Score    Units
testMethod  thrpt  64.579   ops/s

2.2 测试JSON工具的版本

同一款工具不同的版本性能差距往往比较明显,针对被测试的5种JSON解析工具选择了目前主流的版本,本文测试的结果也仅限于以下版本:

Tool版本
FastJson22.0.52
FastJson1.2.83
Jackson2.17.2
Gson2.11.0
Hutool5.8.23

以下为各工具版本对应的Maven依赖:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.52</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-json</artifactId>
    <version>5.8.23</version>
</dependency>

2.3 测试平台

测试代码跑出的得分是依赖于JDK版本和运行代码的机器,不同机器跑出的得分差异是很大的,以下是我的测试机器、JDK版本和IDE版本:

  • 硬件 : MacBook Pro 16GB 13英寸 M2 2022 macOS Ventura 13.5.1 (22G90)
  • JDK : Azul Zulu 17.0.8 - aarch64
  • IDE : IntelliJ IDEA 2024.2 (Ultimate Edition

2.4 测试代码

测试中我针对小JSON中JSON大JSON做序列化和反序列化跑分。其中小、中、大JSON我的定义为:

  • 小JSON

任何一个系统都会有用户信息,我想获取用户详情接口返回的用户信息JSON应该是最能代表我们日常项目开发中对小JSON的定义,所以我选择一条用户信息做为小JSON来做序列化和反序列化测试。以下为用户对象的定义:

@Data
public class User {
    private Long id;
    private String name;
    private String trueName;
    private Integer age;
    private String sex;
    private Date createTime;
}
  • 中JSON

在实际项目中我们除了有大量获取详情接口外,其次应该就是获取列表接口了,一般分页返回数据条数为10条或者20条,这里我选取20条用户信息做为我对中JSON的测试数据,我想这应该是非常具有代表性的中JSON数据。中JSON的数据定义:

private List<User> users;
@Setup
public void setup() {
    users = new ArrayList<>();
    IntStream.range(1, 20).forEach(x -> {
        User user = new User();
        user.setId(1L);
        user.setName(RandomUtil.randomString("公众号:赵侠客",100));
        user.setAge(29);
        user.setSex("男");
        user.setTrueName(RandomUtil.randomString("公众号:赵侠客",100));
        user.setCreateTime(new Date());
        users.add(user);
    });
}
  • 大JSON

每个项目中大JSON可能都不一样,我以博客系统为例,我觉得大JSON可能就是文章正文中的HTML富文本数据,所以测试数据中的大JSON我选择了公众号文章详情页中的HTML富文本数据。以下为大JSON对象定义:

@Data
public class Article {
    private Long id;
    private String author;
    private Long tenantId;
    private String title;
    private String subTitle;
    private String htmlContent;
    private Date publishTime;
}

@Setup
public void setup() throws IOException {
    article = new Article();
    article.setId(10000L);
    article.setTenantId(10000L);
    article.setAuthor("公众号:赵侠客");
    article.setPublishTime(new Date());
    article.setTitle(RandomUtil.randomString("主标题", 100));
    article.setSubTitle(RandomUtil.randomString("副标题", 50));
    article.setHtmlContent(new String(Files.readAllBytes(Paths.get("article.html"))));
}

大JSON部分数据内容

完成对小JSON,中JSON,大JSON数据的定义后,就可以使用JMH做基准测试了,以下为小JSON序列化测试代码:

@State(Scope.Thread)
public class SmallJsonSerialize {
    private User user;
    private ObjectMapper mapper;
    private Gson gson;

    @Setup
    public void setup() {
        user = new User();
        user.setId(1L);
        user.setName("赵侠客");
        user.setAge(29);
        user.setSex("男");
        user.setTrueName("公众号");
        user.setCreateTime(new Date());
        mapper = new ObjectMapper();
        gson = new Gson();
    }

    @TearDown
    public void tearDown() {
        user = null;
        mapper = null;
        gson = null;
    }

    @Benchmark
    public void testFastJson() {
        String json = JSON.toJSONString(user);
    }

    @Benchmark
    public void testFast2Json() {
        String json = com.alibaba.fastjson2.JSON.toJSONString(user);
    }

    @Benchmark
    public void testHutoolJson() {
        String json = JSONUtil.toJsonStr(user);
    }

    @Benchmark
    public void testJackson() throws JsonProcessingException {
        String json = mapper.writeValueAsString(user);
    }

    @Benchmark
    public void testGson() {
        String json = gson.toJson(user);
    }

    @Test
    public void testBenchmark() throws Exception {
        Options options = new OptionsBuilder()
                .include(SmallJsonSerialize.class.getSimpleName())
                .forks(1)
                .threads(1)
                .warmupIterations(1)
                .measurementIterations(1)
                .mode(Mode.Throughput)
                .build();
        new Runner(options).run();
    }
}

三、JSON序列化测试

3.1 小JSON序列化测试

3.1.1 小JSON序列化跑分:

Benchmark    Score        Units
FastJson2    13653527.046 ops/s
FastJson     8502829.931  ops/s
Gson         1217934.274  ops/s
HutoolJson   437293.524   ops/s
Jackson      5779830.068  ops/s

从结果的值来看小JSON序列化都是非常快的,我们的HTTP接口响应时间基本上都是在几十毫秒到几秒之间,对小JSON做一次序列化可以说对我们的接口性能没有任何影响,如果你的项目只有这些小JSON感觉可以闭眼选工具,项目中引用了哪个就用哪个或者哪个用的习惯就用哪个,把主要精力放在业务上没必要太纠结JSON工具的选型。不过今天我们是极客,要有追究极致的精神,我对5种结果做了得分的排名,Score为JMH的跑分,

百分制:最大Score的得100分,其它为 100*(Score/最大值)

3.1.2 小JSON序列化排名:

ToolScore百分制
FastJson213653527100
FastJson850282962.3
Jackson577983042.3
Gson12179348.9
Hutool4372933.2

看到这个排名后我有两点想说的:

  • FastJson2,无敌是多么,多么寂寞
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

3.2 中JSON序列化测试

3.2.1 中JSON序列化跑分:

Benchmark   Score       Units
FastJson2   236910.655  ops/s
FastJson    173386.528  ops/s
Gson        50937.391   ops/s
HutoolJson  10928.165   ops/s
Jackson     212457.203  ops/s

对于中JSON序列化来说分值就大幅度下降了,最差的Hutool 一秒只能序列化1万多次,也就是说做一次JSON转换需要0.1毫秒,做10次也就是1毫秒,如里接口中有大量中JSON序列化调用会对我们接口响应时间有一定影响。

3.2.2 中JSON序列化排名:

ToolScore百分制
FastJson2236910100
Jackson21245789.7
FastJson17338673.2
Gson5093721.5
Hutool109284.6

看到这个排名后我有二点想说的:

  • FastJson2,无敌是多么,多么空虚
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

3.3 大JSON序列化测试

3.3.1 大JSON序列化跑分:

Benchmark    Score     Units
FastJson2   9650.211   ops/s
FastJson    4791.032   ops/s
Gson        5835.649   ops/s
HutoolJson  1035.357   ops/s
Jackson     13398.324  ops/s

大JSON的序列化得分已经降到最差的Hutool-Json执行一次需要1毫秒了,我这还是在M2上跑的,然后我又在PC电脑上跑了一下:

Benchmark   Score      Units
Fast2Json   5788.067   ops/s
FastJson    2480.132   ops/s
Gson        2176.535   ops/s
HutoolJson  455.914    ops/s
Jackson     5276.439   ops/s

上面是在 Intel® Core™ i7-4790K CPU @ 4.00GHz跑的结果,可以看出最差了执行一次JSON序列化需要2毫秒,所参大JSON解析的快慢非常影响我们的接口性能了。

3.3.2 大JSON序列化排名:

ToolScore百分制
Jackson13398100
FastJson2965072.0
Gson583543.6
FastJson479135.8
Hutool10357.7

看到这个排名后我有二点想说的:

  • Jackson,做为SpringBoot默认json序列化工具是有原因的
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

四、JSON反序列化测试

4.1 小JSON反序列化测试

4.1.1 小JSON反序列化跑分:

Benchmark   Score        Units
FastJson2  11654586.191  ops/s
FastJson   5980216.867   ops/s
Gson       2415733.238   ops/s
HutoolJson 855421.710    ops/s
Jackson    3194855.332   ops/s

4.1.2 小JSON反序化排名:

ToolSSSDS变化百分制
FastJson21365352711654586-14.6%100
FastJson85028295980216-29.7%51.3
Jackson12179343194855+162.3%27.4
Gson4372932415733+452.4%20.7
Hutool5779830855421-85.2%7.3

其中:

  • SS( Small Serialize) ,小JSON序列化跑分,
  • SDS(Small Deserializer) ,小JSON反序列化跑分
  • 变化,相比自身小JSON序列化跑分增减百分比

看到这个排名后我有四点想说的:

  • FastJson2,无敌是多么,多么寂寞
  • Jackson&Gson,相比于序列化反序列化快多了
  • FastJson&FastJson2,你很强但是却输给了自己
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

4.2 中JSON反序列化测试

4.2.1 中JSON反序列化跑分:

Benchmark  Score         Units
FastJson2   691572.756   ops/s
FastJson    495493.338   ops/s
Gson        174852.543   ops/s
HutoolJson  37997.839    ops/s
Jackson     216731.673   ops/s

4.2.2 中JSON反序列化排名:

ToolMSMDS变化百分制
FastJson2236910691572+191.9%100
FastJson173386495493+185.8%71.6
Jackson212457216731-2.0%31.3
Gson50937174852+243.3%25.3
Hutool5093737997-25.4%5.5

其中:

  • MS(Medium Serialize) ,中JSON序列化跑分,
  • MDS(Medium Deserializer) ,中JSON反序列化跑分
  • 变化,相比自身中JSON序列化跑分增减百分比

看到这个排名后我有三点想说的:

  • FastJson2,无敌是多么,多么空虚
  • FastJson2&FastJson,不但强还比自己序列化强
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

4.3 大JSON反序列化测试

4.3.1 大JSON反序列化跑分:

Benchmark   Score     Units
FastJson2   8555.106  ops/s
FastJson    9002.889  ops/s
Gson        6141.212  ops/s
HutoolJson  1252.990  ops/s
Jackson     4614.815  ops/s

4.3.2 大JSON反序列化排名:

ToolBSBDS变化百分制
FastJson47919002+87.9100
FastJson296508555-11.395.0
Gson58356141+5.268.2
Jackson133984614-65.651.3
Hutool10351252+20.913.9

其中:

  • BS(Big Serialize) ,大JSON序列化跑分
  • BDS(Big Deserializer) ,大JSON反序列化跑分
  • 变化,相比自身大JSON序列化跑分增减百分比

看到这个排名后我有三点想说的:

  • FastJson2,青出于蓝而胜于蓝,可是你没想到人家还留了一手
  • FastJson,教会徒弟饿死师傅这个道理你是懂的
  • Hutool,@所有人,大家看看自己在项目中有没有使用Hutool-Json,有用到的来下我办公室

排行榜

Tool排名总分百分制SSMSBSSDSMDSBDS
FastJson2状元56710010010072.010010095.0
FastJson榜眼394.269.562.373.235.851.371.6100
Jackson探花34260.342.389.710027.431.351.3
Gson进士188.233.28.921.543.620.725.368.2
Hutool孙山42.27.43.24.67.77.35.513.9

其中:

  • 排名,根据总得分降序
  • 总分,6项得分总和
  • 百分制,总得分最大为100分, 100*(最大总分-自己)/(最大总分)
  • SS,小JSON序列化得分
  • MS,中JSON序列化得分
  • BS,大JSON序列化得分
  • SDS,小JSON反序列化得分
  • MDS,中JSON反序列化得分
  • BDS,大JSON反序列化得分

JSON解析性能排行榜

看到这个排行榜后我有5点想说的:

  • FastJson2,无敌是多么,多么寂寞、无敌是多么,多么空虚
  • FastJson,长江后浪推前浪,前浪被拍在沙滩,你的漏洞那么多,该退休了
  • Jackson,SpringBoot看上的没毛病
  • Gson,你没存在感的原因要从别人找起,不是你不优秀,是优秀的人了太多了
  • Hutool, @公众号 @赵侠客 你们两个工作交接一下,明天不用来了

最后本测试纯个人自娱自乐,由于本人开发水平有限,如果怀疑测试结果,可以评论区交流或者可以下载源码自己跑分:

GitHub:https://github.com/whzhaochao/JsonBenchmark

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2117475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

整合Redis和RedisCacheManger

整合redis springboot在现在的版本中操作Redis数据库用到了lettuce&#xff0c;而不是Jedis&#xff0c;他们各有各的特点。Jedis以Redis命令作为方法名称&#xff0c;学习成本低&#xff0c;简单实用。但是Jedis实例是线程不安全的&#xff0c;多线程环境下需要基于连接池来使…

Java实现一个简单的本地群聊。可以多开Client。

网络编程也有趣的&#xff0c;Java中有对系统网络IO操作的封装包&#xff1a;Socket。现在我们在本地电脑&#xff08;网络&#xff09;用它来模拟一个简单的群聊功能&#xff0c;以便能更好地对网络编程进行深刻的理解。 "Client"去连接"Host",可同时多有…

JavaEE 第23节 TCP的流量控制与阻塞控制详解

目录 前言&#xff08;必读&#xff09;1、滑动窗口背景运行机制 2. 流量控制作用实现机制关键目标 3. 拥塞控制作用实现机制作用 4. 流量控制和拥塞控制的区别作用对象不同触发条件不同控制方式不同 5.总结 前言&#xff08;必读&#xff09; 流量控制&#xff08;Flow Contr…

中科院院士薛其坤:通用量子计算机还得10-20年

说到量子计算机&#xff0c;很多人都抱有不切实际的幻想&#xff0c;甚至认为它无所不能&#xff0c;很快就能取代现有的电子计算机&#xff0c;但事实上&#xff0c;目前的量子计算机只能高效解决特定问题&#xff0c;不具备通用性。在2024年浦江创新论坛上&#xff0c;2023年…

linux日志备份

什么是日志文件?为什么要设立日志文件? 1、日志文件是用来记录事务对数据库的更新操作的文件。2、设立日志文件的目的是: 进行事务故障恢复;进行系统故障恢复;协助后备副本进行介质故障恢复。 但是&#xff0c;随着时间&#xff0c;日志文件内存过于增加&#xff0c;将会导…

creating chat agent with langchain and openai getting no attribute error

题意&#xff1a; 使用 LangChain 和 OpenAI 创建聊天代理时遇到“没有属性错误”&#xff08;Getting "no attribute" error when creating a chat agent with LangChain and OpenAI&#xff09; 问题背景&#xff1a; Im trying to test a chat agent using the …

基于springboot+vue的工作量统计系统(全套)

传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装工作量统计系统软件来发挥其高效地信息处理的作用&#xff0c;可以…

java后端开发的DO、DTO、BO、AO、VO、POJO定义

1.常用文件夹命名规则 pojo&#xff1a; &#xff08;1&#xff09;vo &#xff08;与前端交互的所有对象&#xff0c;包括接参和返回&#xff09; &#xff08;2&#xff09;query &#xff08;查询的筛选条件&#xff0c;前端传参和后端内部传参通用&#xff09; &#x…

[计算机基础四大件学习笔记]计算机组成原理

文章总览&#xff1a;YuanDaiMa2048博客文章总览 计算机基础四大件学习笔记 说明&#xff1a;虽然学习过计算机组成与系统结构、操作系统、计算机网络以及数据结构这四门课程&#xff0c;但是对于这四门课的结合和实际中的应用还是模糊的&#xff0c;因此x想通过网上的一些视频…

Rust语言初探:WebAssembly 入门

Rust语言初探&#xff1a;WebAssembly 入门 前言 在我的印象中&#xff0c;Rust 一直是比较底层的语言&#xff0c;例如在操作系统底层、高性能中间件等底层场景才会看到它的身影。 然而&#xff0c;随着技术的发展&#xff0c;Rust 也开始在前端场景如 WebAssembly 中崭露头…

大数据Flink(一百一十五):Flink SQL的基本概念

文章目录 Flink SQL的基本概念 一、​​​​​​​SQL 中表的概念 二、​​​​​​​​​​​​​​SQL 临时表、永久表 三、​​​​​​​​​​​​​​SQL表类型的定义 四、​​​​​​​​​​​​​​常见的连接器 五、​​​​​​SQL数据视图 1、​​​​​​…

校园气膜馆助力青少年体质发展:少年强则国强—轻空间

青少年是国家的未来&#xff0c;体质的强健与否&#xff0c;直接关系到国家的竞争力和可持续发展。在现代社会&#xff0c;学习和压力并存&#xff0c;青少年的体育锻炼时间不断被压缩&#xff0c;如何提供更为优质的体育设施&#xff0c;帮助他们增强体质&#xff0c;成为学校…

【C/C++】“秒懂”学C/C++不可错过的“经典编程题” — 日期类的经典运用 (含题链接)

“秒懂”学C/C不可错过的“经典编程题” — 日期类的经典运用 (含题链接&#xff09; 1. 计算日期到天数转换(1). 解题思路&#xff1a;(2). 代码实现&#xff1a; 2. 打印日期(1). 解题思路&#xff1a;(2). 代码实现&#xff1a; 3. 日期累加(1). 解题思路&#xff1a;(2). 代…

Java 设计模式-状态模式

目录 一. 概述 二. 主要角色 三. 代码示例 四. 优缺点 优点&#xff1a; 缺点&#xff1a; 五. 常见应用场景 一. 概述 状态模式是一种行为设计模式&#xff0c;它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定…

AES算法与接口解密

文章目录 AES算法基本介绍加密模式模式与IV 接口响应AES解密 AES算法 基本介绍 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。 对称加密算法中加解密密钥都是一样的。 AES 的主要特性&#xff1a; 块加密&#xff1a;AES 是一种分组加密算法&…

Vue day-04

目录 一. vue组件 1.1 为什么用组件 1.2 vue组件 1.3 基础使用 1.4 全局 - 注册使用 1.5 局部 - 注册使用 1.4 用less写的样式 二. Vue组件之间传值(重点) 2.1 父组件向子组件传值 2.2 子组件向父组件传值 2.3 兄弟之间的传递 三. vue生命周期 3.1 含义 3.2 钩子…

phpmyadmin报错mysqli::real_connect(): (HY000/1045): Access denied for user ‘

问题分析 这是因为本身还安装了MySQL&#xff0c;导致发生冲突&#xff0c;只需要找到自己安装的进行关闭即可 方法 在任务管理器(快捷键&#xff1a;ctrlaltdelete)-服务中&#xff0c;找到对应的MySQL进行关闭

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端&#xff0c;一般来说需要版本检测和自动更新功能&#xff0c;这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤&#xff1a; 读取本地应用版本拉取远程版本并比较两个版本如果需要升级&…

数字化转型的战略规划应该怎么做?(附IBM-IT战略规划方法论PPT下载)

IBM-IT战略规划方法论PPT-下载链接见文末~ 数字化转型的战略规划是一个系统而复杂的过程&#xff0c;需要从多个维度进行考虑和规划。以下是一些关键步骤和建议&#xff0c;以帮助企业制定有效的数字化转型战略规划&#xff1a; 1. 明确数字化转型愿景和目标 设定愿景&#…

基于ONSEMI电源管理芯片NCP1607之AC300V高输入电压36W调色温智能电源

NCP1607PFC在LED智能电源PFC处理部分性价比高&#xff0c;输入电压范围宽到AC90-300V,母线电压420V导致高压低电流整机光效高&#xff0c;成熟芯片可靠新高&#xff0c;没有任何纹波与频闪&#xff0c;智能护眼。 ►场景应用图 ►产品实体图 ►展示板照片 ►方案方块图 ►核心…