improve serialize performance

This commit is contained in:
温少
2012-04-27 00:41:59 +08:00
parent 5dc8e8b7c0
commit bd49960327
4 changed files with 55 additions and 83 deletions
@@ -130,6 +130,12 @@ public class ASMSerializerFactory implements Opcodes {
for (FieldInfo fieldInfo : getters) {
Class<?> propertyClass = fieldInfo.getFieldClass();
{
FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldPrefix",
"Ljava/lang/reflect/Type;");
fw.visitEnd();
}
if (propertyClass.isPrimitive()) {
continue;
} else if (propertyClass == String.class) {
@@ -169,9 +175,9 @@ public class ASMSerializerFactory implements Opcodes {
}
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getDeclaringClass())));
if (fieldInfo.getMethod() != null) {
mw.visitLdcInsn(fieldInfo.getMethod().getName());
mw.visitMethodInsn(INVOKESTATIC, getType(ASMUtils.class), "getMethodType",
@@ -364,20 +370,13 @@ public class ASMSerializerFactory implements Opcodes {
Label else_ = new Label();
Label writeClass_ = new Label();
mw.visitVarInsn(ALOAD, context.serializer());
mw.visitVarInsn(ALOAD, context.paramFieldType());
mw.visitVarInsn(ALOAD, context.obj());
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "isWriteClassName",
"(Ljava/lang/reflect/Type;Ljava/lang/Object;)Z");
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "WriteClassName",
"L" + getType(SerializerFeature.class) + ";");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
"(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
mw.visitJumpInsn(IFEQ, else_);
// mw.visitVarInsn(ALOAD, context.var("out"));
// mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "WriteClassName",
// "L" + getType(SerializerFeature.class) + ";");
// mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
// "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
// mw.visitJumpInsn(IFEQ, else_);
// mw.visitVarInsn(ALOAD, context.paramFieldType());
// mw.visitJumpInsn(IFNULL, writeClass_);
@@ -469,6 +468,7 @@ public class ASMSerializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, context.var("parent"));
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "setContext",
"(Lcom/alibaba/fastjson/serializer/SerialContext;)V");
}
private void initNature(Class<?> clazz, MethodVisitor mw, Context context) {
@@ -1044,9 +1044,10 @@ public class ASMSerializerFactory implements Opcodes {
"(Ljava/lang/Object;Ljava/lang/Object;)V");
} else {
// fieldInfo.getName() + "_asm_fieldType"
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;");
mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_fieldType",
"Ljava/lang/reflect/Type;");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
@@ -292,7 +292,7 @@ public final class SerializeWriter extends Writer {
if (buf.length <= 1024 * 8) {
bufLocal.set(new SoftReference<char[]>(buf));
}
this.buf = null;
}
@@ -630,6 +630,10 @@ public final class SerializeWriter extends Writer {
}
private void writeStringWithDoubleQuote(String text, final char seperator) {
writeStringWithDoubleQuote(text, seperator, true);
}
private void writeStringWithDoubleQuote(String text, final char seperator, boolean checkSpecial) {
// final boolean[] specicalFlags_doubleQuotes =
// CharTypes.specicalFlags_doubleQuotes;
// final int len_flags = specicalFlags_doubleQuotes.length;
@@ -749,16 +753,18 @@ public final class SerializeWriter extends Writer {
int specialCount = 0;
int lastSpecialIndex = -1;
char lastSpecial = '\0';
for (int i = start; i < end; ++i) {
char ch = buf[i];
if (checkSpecial) {
for (int i = start; i < end; ++i) {
char ch = buf[i];
if (ch < CharTypes.specicalFlags_doubleQuotes.length
&& CharTypes.specicalFlags_doubleQuotes[ch] //
|| (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;
if (ch < CharTypes.specicalFlags_doubleQuotes.length
&& CharTypes.specicalFlags_doubleQuotes[ch] //
|| (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;
}
}
}
@@ -932,14 +938,14 @@ public final class SerializeWriter extends Writer {
name.getChars(0, nameLen, buf, start + 2);
buf[nameEnd + 1] = keySeperator;
if (value) {
System.arraycopy(":true".toCharArray(), 0, buf, nameEnd + 2, 5);
} else {
System.arraycopy(":false".toCharArray(), 0, buf, nameEnd + 2, 6);
}
}
public void writeFieldValue1(char seperator, String name, boolean value) {
write(seperator);
writeFieldName(name);
@@ -1122,54 +1128,6 @@ public final class SerializeWriter extends Writer {
count = newcount;
int specialCount = 0;
int lastSpecialIndex = -1;
char lastSpecial = '\0';
for (int i = nameStart; i < nameEnd; ++i) {
char ch = buf[i];
if (ch == '\b' || ch == '\n' || ch == '\r' || ch == '\f' || ch == '\\'
|| ch == '"' //
|| (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;
}
}
if (specialCount > 0) {
newcount += specialCount;
if (newcount > buf.length) {
expandCapacity(newcount);
}
count = newcount;
}
if (specialCount == 1) {
System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, nameEnd - lastSpecialIndex - 1);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
nameEnd++;
} else if (specialCount > 1) {
System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, nameEnd - lastSpecialIndex - 1);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
nameEnd++;
for (int i = lastSpecialIndex - 2; i >= nameStart; --i) {
char ch = buf[i];
if (ch == '\b' || ch == '\n' || ch == '\r' || ch == '\f' || ch == '\\'
|| ch == '"' //
|| (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
System.arraycopy(buf, i + 1, buf, i + 2, nameEnd - i - 1);
buf[i] = '\\';
buf[i + 1] = replaceChars[(int) ch];
nameEnd++;
}
}
}
buf[nameEnd] = '\"';
int index = nameEnd + 1;
@@ -1190,11 +1148,15 @@ public final class SerializeWriter extends Writer {
value.getChars(0, valueLen, buf, valueStart);
specialCount = 0;
lastSpecialIndex = -1;
lastSpecial = '\0';
int specialCount = 0;
int lastSpecialIndex = -1;
char lastSpecial = '\0';
for (int i = valueStart; i < valueEnd; ++i) {
char ch = buf[i];
if (ch >= 'a') {
continue;
}
if (ch == '\b' || ch == '\n' || ch == '\r' || ch == '\f' || ch == '\\'
|| ch == '"' //
|| (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))
@@ -1249,9 +1211,18 @@ public final class SerializeWriter extends Writer {
writeNull();
return;
}
if (isEnabled(SerializerFeature.WriteEnumUsingToString)) {
writeFieldValue(seperator, name, value.name());
if (isEnabled(SerializerFeature.UseSingleQuotes)) {
writeFieldValue(seperator, name, value.name());
} else {
write(seperator);
writeFieldName(name);
writeStringWithDoubleQuote(value.name(), (char) 0, false);
return;
}
//writeStringWithDoubleQuote
} else {
writeFieldValue(seperator, name, value.ordinal());
}
@@ -14,7 +14,7 @@ public class BenchmarkTest extends TestCase {
BenchmarkExecutor executor = new BenchmarkExecutor();
executor.setExecuteCount(4);
executor.getCodecList().add(new FastjsonCodec());
// executor.getCodecList().add(new JacksonCodec());
executor.getCodecList().add(new JacksonCodec());
//
// executor.getCodecList().add(new SimpleJsonCodec());
// executor.getCodecList().add(new JsonLibCodec());
@@ -62,7 +62,7 @@ public class EishayEncode extends BenchmarkCase {
@Override
public void execute(Codec codec) throws Exception {
String text = codec.encode(mediaContent);
String text = codec.encode(mediaContent.media);
if (text == null) {
throw new Exception();
}