4.2 KiB
4.2 KiB
反序列化CodeGen算法介绍
fastjson2会使用codegen来优化反序列化的性能,用到的codegen技术包括:
- ASM 基于内置asm 9.2裁剪版实现的动态字节码生成类
- Annotation Process Tools(APT)
1. 实现算法介绍
上图中算法1是常规实现;算法2是fastjson2的实现(最初是dsljson引入,被fastjson借鉴);算法3是新引入的实现
我们要将json反序列化为如下的Image类
@Data
public class Image {
private int height;
private Size size;
private String title;
private String uri;
private int width;
}
生成如下的代码来快速将json中的name和字段关联起来:
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中的实现
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