fastjson2/docs/reader_codegen.md

139 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 反序列化CodeGen算法介绍
fastjson2会使用codegen来优化反序列化的性能用到的codegen技术包括
* ASM 基于内置asm 9.2裁剪版实现的动态字节码生成类
* Annotation Process Tools(APT)
## 1. 实现算法介绍
![image](reader_codegen_01.png)
上图中算法1是常规实现算法2是fastjson2的实现最初是dsljson引入被fastjson借鉴算法3是新引入的实现
我们要将json反序列化为如下的Image类
```java
@Data
public class Image {
private int height;
private Size size;
private String title;
private String uri;
private int width;
}
```
生成如下的代码来快速将json中的name和字段关联起来
```java
public final class Image_FASTJSONReader
extends com.alibaba.fastjson2.reader.ObjectReader5 {
public Object readObject(
com.alibaba.fastjson2.JSONReader jsonReader,
java.lang.reflect.Type fieldType,
Object fieldName,
long features
) {
Image object = new Image();
while (!jsonReader.nextIfObjectEnd()) {
switch (jsonReader.getRawInt()) {
// '"' | ('w' << 8) | ('i' << 16) | ('d' << 24) == 1684633378
// 't' | ('h' << 8) | ('"' << 16) | (':' << 24) == 975333492
case 1684633378: // "wid
if (jsonReader.nextIfName4Match5(975333492)) { // th":
object.setWidth(
jsonReader.readInt32Value()
);
continue;
}
break;
// '"' | ('h' << 8) | ('e' << 16) | ('i' << 24) == 1768253474
// 'g' | ('h' << 8) | ('t' << 16) | ('"' << 24) == 578054247
case 1768253474: // "hei
if (jsonReader.nextIfName4Match6(578054247)) { // ght"
object.setHeight(
jsonReader.readInt32Value()
);
continue;
}
break;
// '"' | ('u' << 8) | ('r' << 16) | ('i' << 24) == 1769108770
case 1769108770: // "uri"
if (jsonReader.nextIfName4Match3()) {
object.setUri(
jsonReader.readString()
);
continue;
}
break;
// ...
default:
break;
}
// ....
}
return object;
}
}
```
相关方法在JSONReader中的实现
```java
class JSONReaderUTF8 implements JSONReader {
public final int getRawInt() {
if (offset + 3 < bytes.length) {
return UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 1);
}
return 0;
}
public boolean nextIfName4Match3() {
offset += 5;
if (bytes[offset - 2] != '"' || bytes[offset - 1] != ':') {
return false;
}
// ...
return true;
}
public final boolean nextIfName4Match4(byte c4) {
offset += 6;
if (bytes[offset - 3] != c4 || bytes[offset - 2] != '"' || bytes[offset - 1] != ':') {
return false;
}
// ...
return true;
}
public boolean nextIfName4Match5(int name1) {
offset += 7;
if (UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 4) != name1) {
return false;
}
// ...
return true;
}
public boolean nextIfName4Match6(int name1) {
offset += 8;
if (UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 5) != name1 || bytes[offset - 1] != ':') {
return false;
}
// ...
return true;
}
}
```
这样的实现好处是不需要将key读取出来也不需要将使用JSONReader#readFieldNameHashCode通过key的前缀3个字符读取一个int值使用switch来路由到相应字段的处理。
## 2. 算法实现代码
生成代码的实现:
* ASM实现 com.alibaba.fastjson2.reader.ObjectReaderCreatorASM#genRead243
* APT实现 com.alibaba.fastjson2.internal.processor.JSONCompiledAnnotationProcessor.genRead243