FlatBuffer Java Bean自由转换

性能-来自谷歌

FlatBuffers (binary)Protocol Buffers LITERapid JSONFlatBuffers (JSON)pugixmlRaw structs
Decode + Traverse + Dealloc (1 million times, seconds)0.083025831051960.02
Decode / Traverse / Dealloc (breakdown)0 / 0.08 / 0220 / 0.15 / 81294 / 0.9 / 28770 / 0.08 / 3541 / 3.9 / 1500 / 0.02 / 0
Encode (1 million times, seconds)3.21856501692730.15
Wire format size (normal / zlib, bytes)344 / 220228 / 1741475 / 3221029 / 2981137 / 341312 / 187
Memory needed to store decoded wire (bytes / blocks)0 / 0760 / 2065689 / 4328 / 134194 / 30 / 0
Transient memory allocated during decode (KB)011314340
Generated source code size (KB)4610400
Field access in handwritten traversal codetyped accessorstyped accessorsmanual error checkingtyped accessorsmanual error checkingtyped but no safety
Library source code (KB)15some subset of 380087433270

定义一个结构schema


namespace io.flatbutterx.sample;

table ReposList {
    repos : [Repo];
}

table Repo {
    id : long;
    name : string;
    full_name : string;
    owner : User;
    html_url : string;
    description : string;
}

table User {
    login : string;
    id : long;
}

root_type ReposList;

flatc -b -j schema.fbs进行编译。产生的文件如下

public final class User extends Table {
  public static User getRootAsUser(ByteBuffer _bb) { return getRootAsUser(_bb, new User()); }
  public static User getRootAsUser(ByteBuffer _bb, User obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
  public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
  public User __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public String login() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
  public ByteBuffer loginAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
  public ByteBuffer loginInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 4, 1); }
  public long id() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }

  public static int createUser(FlatBufferBuilder builder,
      int loginOffset,
      long id) {
    builder.startObject(2);
    User.addId(builder, id);
    User.addLogin(builder, loginOffset);
    return User.endUser(builder);
  }

  public static void startUser(FlatBufferBuilder builder) { builder.startObject(2); }
  public static void addLogin(FlatBufferBuilder builder, int loginOffset) { builder.addOffset(0, loginOffset, 0); }
  public static void addId(FlatBufferBuilder builder, long id) { builder.addLong(1, id, 0L); }
  public static int endUser(FlatBufferBuilder builder) {
    int o = builder.endObject();
    return o;
  }
}

里面一堆方法

  1. getRootAsUser(ByteBuffer _bb), 这个作用是将byte数组产生User对象。
  2. createUser这个作用是是使用参数创建一个User对象。参数的第一个是builder,后面的是参数,要注意的是loginOffset需要builder createString之后在获取到offset在使用,比较麻烦,如果是数组的话,更麻烦

举个例子Weapon有个数组为weapons,通过下面的代码我们看下怎样进行赋值

        int[] weaps = new int[2];
        weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
        weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);

        int weapons = Monster.createWeaponsVector(builder, weaps);

            int orc = Monster.createMonster(builder, name, weapons);
            builder.finish(orc);

首先需要创建一个数组,通过createWeapon创建单个元素的偏移,然后将偏移放入数组。 然后将数组作为输入createWeaponsVector获取数组的偏移,然后才能使用,比较麻烦? 想查看对象内容怎么办?都在数组里面,手写toString? #No

自动生成?

  • 生成一个Java Bean对象
  • Java Bean与FlatBuffer的相互转换,比如ORM之类的可以使用。
  • Java Bean 与JSON的相互转换
public final class UserFB extends FlatBufferMapper<UserFB> {
 public Long id;

 public String login;

 @Override
 public UserFB parse(JsonParser jsonParser) throws IOException {
   UserFB instance = new UserFB();
   if (jsonParser.getCurrentToken() == null) {
     jsonParser.nextToken();
   }
   if (jsonParser.getCurrentToken() != JsonToken.START_OBJECT) {
     jsonParser.skipChildren();
     return null;
   }
   while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
     String fieldName = jsonParser.getCurrentName();
     jsonParser.nextToken();
     parseField(instance, fieldName, jsonParser);
     jsonParser.skipChildren();
   }
   return instance;
 }

 @Override
 public void parseField(UserFB instance, String fieldName, JsonParser jsonParser) throws
     IOException {
   if ("id".equals(fieldName)) {
     instance.id = jsonParser.getCurrentToken() == JsonToken.VALUE_NULL ? null : Long.valueOf(jsonParser.getValueAsLong());
   } else if ("login".equals(fieldName)) {
     instance.login = jsonParser.getValueAsString(null);
   }
 }

 @Override
 public void serialize(UserFB object, JsonGenerator jsonGenerator, boolean writeStartAndEnd) throws
     IOException {
   if (writeStartAndEnd) {
     jsonGenerator.writeStartObject();
   }
   if (object.id != null) {
     jsonGenerator.writeNumberField("id", object.id);
   }
   if (object.login != null) {
     jsonGenerator.writeStringField("login", object.login);
   }
   if (writeStartAndEnd) {
     jsonGenerator.writeEndObject();
   }
 }

 @Override
 public ByteBuffer toFlatBuffer(UserFB object) throws IOException {
   FlatBufferBuilder bufferBuilder = new FlatBufferBuilder();
   int offset = toFlatBufferOffset(bufferBuilder);
   bufferBuilder.finish(offset);
   return bufferBuilder.dataBuffer();
 }

 @Override
 public int toFlatBufferOffset(FlatBufferBuilder bufferBuilder) throws IOException {
   return User.createUser(bufferBuilder,bufferBuilder.createString(this.login),this.id);
 }

 @Override
 public UserFB flatBufferToBean(Object object) throws IOException {
   User flatObj = (User) object;
   this.id = flatObj.id();
   this.login = flatObj.login();
   return this;
 }
}

  1. ByteBuffer toFlatBuffer(UserFB object) Java对象转换成FlatBuffer的字节流
  2. flatBufferToBean(Object object) 将FlatBuffer对象转换成JavaBean。

愉快的写代码吧,只要toFlatBuffer和flatBufferToBean就可以了。

神奇

只需要给生成的FlatBuffer添加一个注解就行了 @FlatBufferSrc

然后注解处理器会处理FlatBuffer,解析里面的字段,然后最终组合出来Java Bean对象,就跟上面你看到的那样

引入

注解处理器
annotationProcessor "o.flatbufferx:flatbufferx-compiler:last-version"
compile  "io.flatbufferx:core:last-version"
last-version=1.0.0

代码仓库

转载于:https://my.oschina.net/tib/blog/2208880

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值