Skip to content

[Java] About High performance implementation tips #788

@leonchen83

Description

@leonchen83

In fury doc about High performance feature

reduce memory access by inline variable in generated code.
reduce virtual method invocation by inline call in generated code.
reduce conditional branching.
reduce hash lookup.

when we use fury to serialize class. fury generate following class code.

DefFuryRefCodec_2102608770_1670675563_330739404.java

package cn.nextop.gadget.core.marshal.support;

import java.util.List;
import java.util.Map;
import java.util.Set;
import io.fury.Fury;
import io.fury.memory.MemoryBuffer;
import io.fury.resolver.MapRefResolver;
import io.fury.resolver.ClassInfo;
import io.fury.resolver.ClassInfoCache;
import io.fury.resolver.ClassResolver;
import io.fury.builder.Generated;
import io.fury.serializer.CodegenSerializer.LazyInitBeanSerializer;
import io.fury.serializer.Serializers.EnumSerializer;
import io.fury.serializer.Serializer;
import io.fury.serializer.StringSerializer;
import io.fury.serializer.ObjectSerializer;
import io.fury.serializer.CompatibleSerializer;
import io.fury.serializer.CollectionSerializers.CollectionSerializer;
import io.fury.serializer.MapSerializers.MapSerializer;
import io.fury.builder.Generated.GeneratedObjectSerializer;

public final class DefFuryRefCodec_2102608770_1670675563_330739404 extends GeneratedObjectSerializer {

  private final MapRefResolver refResolver;
  private final ClassResolver classResolver;
  private final StringSerializer strSerializer;
  private final Fury fury;
  private final EnumSerializer enumSerializer;
  private final EnumSerializer enumSerializer1;
  private final EnumSerializer enumSerializer2;
  private ClassInfo bigDecimalClassInfo;
  private ClassInfo dateClassInfo;
  private final ClassInfoCache bigDecimal1ClassInfoCache;
  private final ClassInfoCache date1ClassInfoCache;

  public DefFuryRefCodec_2102608770_1670675563_330739404(Fury fury, Class classType) {
      super(fury, classType);
      this.fury = fury;
      fury.getClassResolver().setSerializerIfAbsent(classType, this);
  
      io.fury.resolver.RefResolver refResolver0 = fury.getRefResolver();
      refResolver = ((MapRefResolver)refResolver0);
      classResolver = fury.getClassResolver();
      strSerializer = fury.getStringSerializer();
      enumSerializer = ((EnumSerializer)classResolver.getSerializer(cn.nextop.gadget.core.marshal.support.TypeA.class));
      enumSerializer1 = ((EnumSerializer)classResolver.getSerializer(cn.nextop.gadget.core.marshal.support.TypeB.class));
      enumSerializer2 = ((EnumSerializer)classResolver.getSerializer(cn.nextop.gadget.core.marshal.support.TypeC.class));
      bigDecimalClassInfo = classResolver.nilClassInfo();
      dateClassInfo = classResolver.nilClassInfo();
      bigDecimal1ClassInfoCache = classResolver.nilClassInfoCache();
      date1ClassInfoCache = classResolver.nilClassInfoCache();
  }

  private void writeFields(MemoryBuffer memoryBuffer, cn.nextop.gadget.core.marshal.support.Def def1) {
      Object object1 = io.fury.util.Platform.getObject(def1, 28L);
      cn.nextop.gadget.core.marshal.support.TypeA t1 = (cn.nextop.gadget.core.marshal.support.TypeA)object1;
      if ((t1 == null)) {
          memoryBuffer.writeByte(((byte)-3));
      } else {
          memoryBuffer.writeByte(((byte)0));
          enumSerializer.write(memoryBuffer, t1);
      }
      Object object22 = io.fury.util.Platform.getObject(def1, 32L);
      cn.nextop.gadget.core.marshal.support.TypeB t2 = (cn.nextop.gadget.core.marshal.support.TypeB)object22;
      if ((t2 == null)) {
          memoryBuffer.writeByte(((byte)-3));
      } else {
          memoryBuffer.writeByte(((byte)0));
          enumSerializer1.write(memoryBuffer, t2);
      }
      Object object33 = io.fury.util.Platform.getObject(def1, 36L);
      cn.nextop.gadget.core.marshal.support.TypeC t3 = (cn.nextop.gadget.core.marshal.support.TypeC)object33;
      if ((t3 == null)) {
          memoryBuffer.writeByte(((byte)-3));
      } else {
          memoryBuffer.writeByte(((byte)0));
          enumSerializer2.write(memoryBuffer, t3);
      }
      Object object44 = io.fury.util.Platform.getObject(def1, 20L);
      String f3 = (String)object44;
      if ((f3 == null)) {
          memoryBuffer.writeByte(((byte)-3));
      } else {
          memoryBuffer.writeByte(((byte)0));
          StringSerializer.writeJDK11String(memoryBuffer, f3);
      }
  }

  private void writeClassAndObject(MemoryBuffer memoryBuffer1, java.math.BigDecimal bigDecimal) {
      ClassResolver classResolver = this.classResolver;
      Class value0 = bigDecimalClassInfo.getCls();
      Class cls = bigDecimal.getClass();
      if ((value0 != cls)) {
          bigDecimalClassInfo = classResolver.getClassInfo(cls);
      }
      short value1 = bigDecimalClassInfo.getClassId();
      if ((value1 == ((short)0))) {
          memoryBuffer1.writeByte(((byte)0));
          classResolver.writeEnumStringBytes(memoryBuffer1, bigDecimalClassInfo.getPackageNameBytes());
          classResolver.writeEnumStringBytes(memoryBuffer1, bigDecimalClassInfo.getClassNameBytes());
      } else {
          int value2 = memoryBuffer1.writerIndex();
          memoryBuffer1.increaseWriterIndex(3);
          memoryBuffer1.unsafePut(value2, ((byte)1));
          memoryBuffer1.unsafePutShort((value2 + 1), value1);
      }
      bigDecimalClassInfo.getSerializer().write(memoryBuffer1, bigDecimal);
  }

  private void writeClassAndObject1(MemoryBuffer memoryBuffer2, java.util.Date date) {
      ClassResolver classResolver = this.classResolver;
      Class value3 = dateClassInfo.getCls();
      Class cls0 = date.getClass();
      if ((value3 != cls0)) {
          dateClassInfo = classResolver.getClassInfo(cls0);
      }
      short value4 = dateClassInfo.getClassId();
      if ((value4 == ((short)0))) {
          memoryBuffer2.writeByte(((byte)0));
          classResolver.writeEnumStringBytes(memoryBuffer2, dateClassInfo.getPackageNameBytes());
          classResolver.writeEnumStringBytes(memoryBuffer2, dateClassInfo.getClassNameBytes());
      } else {
          int value5 = memoryBuffer2.writerIndex();
          memoryBuffer2.increaseWriterIndex(3);
          memoryBuffer2.unsafePut(value5, ((byte)1));
          memoryBuffer2.unsafePutShort((value5 + 1), value4);
      }
      dateClassInfo.getSerializer().write(memoryBuffer2, date);
  }

  private void writeFields1(MemoryBuffer memoryBuffer3, cn.nextop.gadget.core.marshal.support.Def def2) {
      Object object00 = io.fury.util.Platform.getObject(def2, 24L);
      java.math.BigDecimal f4 = (java.math.BigDecimal)object00;
      if ((!refResolver.writeRefOrNull(memoryBuffer3, f4))) {
          this.writeClassAndObject(memoryBuffer3, f4);
      }
      Object object51 = io.fury.util.Platform.getObject(def2, 16L);
      java.util.Date f2 = (java.util.Date)object51;
      if ((f2 == null)) {
          memoryBuffer3.writeByte(((byte)-3));
      } else {
          memoryBuffer3.writeByte(((byte)0));
          this.writeClassAndObject1(memoryBuffer3, f2);
      }
  }

  private void readFields(cn.nextop.gadget.core.marshal.support.Def def3, MemoryBuffer memoryBuffer4) {
      if ((memoryBuffer4.readByte() != ((byte)-3))) {
          Enum value6 = enumSerializer.read(memoryBuffer4);
          io.fury.util.Platform.putObject(def3, 28L, ((cn.nextop.gadget.core.marshal.support.TypeA)value6));
      } else {
          io.fury.util.Platform.putObject(def3, 28L, null);
      }
      if ((memoryBuffer4.readByte() != ((byte)-3))) {
          Enum value9 = enumSerializer1.read(memoryBuffer4);
          io.fury.util.Platform.putObject(def3, 32L, ((cn.nextop.gadget.core.marshal.support.TypeB)value9));
      } else {
          io.fury.util.Platform.putObject(def3, 32L, null);
      }
      if ((memoryBuffer4.readByte() != ((byte)-3))) {
          Enum value12 = enumSerializer2.read(memoryBuffer4);
          io.fury.util.Platform.putObject(def3, 36L, ((cn.nextop.gadget.core.marshal.support.TypeC)value12));
      } else {
          io.fury.util.Platform.putObject(def3, 36L, null);
      }
      if ((memoryBuffer4.readByte() != ((byte)-3))) {
          io.fury.util.Platform.putObject(def3, 20L, strSerializer.readJava11String(memoryBuffer4));
      } else {
          io.fury.util.Platform.putObject(def3, 20L, null);
      }
  }

  private void readFields1(cn.nextop.gadget.core.marshal.support.Def def4, MemoryBuffer memoryBuffer5) {
      ClassResolver classResolver = this.classResolver;
      MapRefResolver refResolver = this.refResolver;
      int refId = refResolver.tryPreserveRefId(memoryBuffer5);
      if ((refId >= ((byte)-1))) {
          Object object6 = classResolver.readClassInfo(memoryBuffer5, bigDecimal1ClassInfoCache).getSerializer().read(memoryBuffer5);
          refResolver.setReadObject(refId, object6);
          io.fury.util.Platform.putObject(def4, 24L, ((java.math.BigDecimal)object6));
      } else {
          io.fury.util.Platform.putObject(def4, 24L, ((java.math.BigDecimal)refResolver.getReadObject()));
      }
      if ((memoryBuffer5.readByte() != ((byte)-3))) {
          Object object7 = classResolver.readClassInfo(memoryBuffer5, date1ClassInfoCache).getSerializer().read(memoryBuffer5);
          io.fury.util.Platform.putObject(def4, 16L, ((java.util.Date)object7));
      } else {
          io.fury.util.Platform.putObject(def4, 16L, null);
      }
  }

  @Override public final void write(MemoryBuffer buffer, Object obj) {
      cn.nextop.gadget.core.marshal.support.Def def5 = (cn.nextop.gadget.core.marshal.support.Def)obj;
      buffer.writeInt(557608220);
      buffer.grow(4);
      byte[] base = buffer.getHeapMemory();
      long writerAddr = buffer.getUnsafeWriterAddress();
      MemoryBuffer.unsafePutInt(base, writerAddr, io.fury.util.Platform.getInt(def5, 12L));
      buffer.increaseWriterIndexUnsafe(4);
      this.writeFields(buffer, def5);
      this.writeFields1(buffer, def5);
  }

  @Override public final Object read(MemoryBuffer buffer) {
      ObjectSerializer.checkClassVersion(fury, buffer.readInt(), 557608220);
      cn.nextop.gadget.core.marshal.support.Def def6 = new cn.nextop.gadget.core.marshal.support.Def();
      refResolver.reference(def6);
      byte[] heapBuffer = buffer.getHeapMemory();
      long readerAddr = buffer.getUnsafeReaderAddress();
      buffer.checkReadableBytes(4);
      io.fury.util.Platform.putInt(def6, 12L, MemoryBuffer.unsafeGetInt(heapBuffer, readerAddr));
      buffer.increaseReaderIndexUnsafe(4);
      this.readFields(def6, buffer);
      this.readFields1(def6, buffer);
      return def6;
  }

}

Could you help me to point out high performance implementation tips aboult above code ?
We are investigating the availability of fury framework and want to integrate into our system.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions