数据的序列化是程序代码里面必不可少的组成部分,当我们讨论到数据序列化的性能的时候,需要了解有哪些候选的方案,他们各自的优缺点是什么。
数据序列化的行为可能发生在数据传递过程中的任何阶段,例如网络传输,不同进程间数据传递,不同类之间的参数传递,把数据存储到磁盘上等等。通常情况下,我们会把那些需要序列化的类实现Serializable接口,但是这种传统的做法效率不高,实施的过程会消耗更多的内存。
但是我们如果使用GSON库来处理这个序列化的问题,不仅仅执行速度更快,内存的使用效率也更高。Android的XML布局文件会在编译的阶段被转换成更加复杂的格式,具备更加高效的执行性能与更高的内存使用效率。
JSON 的可读性很强,但是序列化和反序列化性能却是最差的。解析的时候,JSON 解析器首先,需要在内存中初始化一个对应的数据结构,这个事件经常会消耗 100ms ~ 200ms;解析过程中,要产生大量的临时变量,造成 Java 虚拟机的 GC 和内存抖动,解析 20KB的数据,大概会消耗 100KB 的临时内存。
可见,FlatBuffers几乎从空间和时间复杂度上完胜其他技术。
FlatBuffer是基于二进制文件的,json是基于字符串的。
FlatBuffers是一个开源的跨平台数据序列化库,可以应用到几乎任何语言(C++, C#, Go, Java, JavaScript, PHP, Python)。
最开始是 Google 为游戏或者其他对性能要求很高的应用开发的。项目地址在GitHub上。官方的文档https://github.com/google/flatbuffers。
{
"result": [
{
"id": "110000",
"title": "北京市",
"city": [
{
"id": "110100",
"title": "北京市",
"children": [
{
"id": "110101",
"title": "东城区",
"value": 1
}
]
}
]
}]}
table ResultList {
result : [Result];
}
table Result {
id : string;
title : string;
city : [City];
}
table City {
id : string;
title : string;
children : [Children];
}
table Children {
id : string;
title : string;
value:int;
isCore:bool;
code:long;
}
root_type ResultList;
flatc -j -b address.fbs
文件可能会报错,是包名以及导包的问题。
下面以其中一个文件为例。
package cn.gxh.property.Lsn13;// automatically generated, do not modify
//这个可以删掉,上面包名已经存在
package ;
import java.nio.*;
import java.lang.*;
import java.util.*;
//这个可以删掉
import com.google.flatbuffers.*;
//下面报红的话是导包的问题
public class ResultList extends Table {
public static ResultList getRootAsResultList(ByteBuffer _bb) { return getRootAsResultList(_bb, new ResultList()); }
public static ResultList getRootAsResultList(ByteBuffer _bb, ResultList obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public ResultList __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
public Result result(int j) { return result(new Result(), j); }
public Result result(Result obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int resultLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; }
public static int createResultList(FlatBufferBuilder builder,
int result) {
builder.startObject(1);
ResultList.addResult(builder, result);
return ResultList.endResultList(builder);
}
public static void startResultList(FlatBufferBuilder builder) { builder.startObject(1); }
public static void addResult(FlatBufferBuilder builder, int resultOffset) { builder.addOffset(0, resultOffset, 0); }
public static int createResultVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startResultVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endResultList(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
public static void finishResultListBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
};
private void serialize() {
FlatBufferBuilder builder = new FlatBufferBuilder();
//县区
int children1 = Children.createChildren(builder, builder.createString("1001"),
builder.createString("海淀区"), 1, true, 10000009);
int children2 = Children.createChildren(builder, builder.createString("1002"),
builder.createString("朝阳区"), 2, true, 10000008);
int[] childrens = new int[2];
childrens[0] = children1;
childrens[1] = children2;
int childrenVector = City.createChildrenVector(builder, childrens);
//市
int city = City.createCity(builder, builder.createString("101"),
builder.createString("北京市"), childrenVector);
int[] cities = new int[2];
cities[0] = city;
int cityVector = Result.createCityVector(builder, cities);
int result = Result.createResult(builder, builder.createString("100"),
builder.createString("北京市1"), cityVector);
int[] results=new int[2];
results[0]=result;
int resultVector = ResultList.createResultVector(builder, results);
ResultList.startResultList(builder);
ResultList.addResult(builder, resultVector);
int rootResult = ResultList.endResultList(builder);
ResultList.finishResultListBuffer(builder, rootResult);
//-------保存数据到文件------
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "address.txt");
if (file.exists()) {
file.delete();
}
ByteBuffer byteBuffer = builder.dataBuffer();
FileOutputStream fos = null;
FileChannel channel = null;
try {
fos = new FileOutputStream(file);
channel = fos.getChannel();
while (byteBuffer.hasRemaining()) {
channel.write(byteBuffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
if (channel != null) {
channel.close();
}
} catch (Exception e) {
}
}
//------读取文件--------
FileInputStream fis = null;
FileChannel readChannel = null;
try {
fis = new FileInputStream(file);
readChannel = fis.getChannel();
ByteBuffer byteBuffer1 = ByteBuffer.allocate(1024);
int readBytes = 0;
while ((readBytes = readChannel.read(byteBuffer1)) != -1) {
}
//把指针回到最初的状态
byteBuffer1.flip();
ResultList resultList = ResultList.getRootAsResultList(byteBuffer1);
Global.showToast(resultList.result(0).id()+";"+resultList.result(0).title());
Log.d("gxh",resultList.result(0).id()+";"+resultList.result(0).title());
} catch (Exception e) {
}finally {
try {
if (fis != null) {
fis.close();
}
if (readChannel != null) {
readChannel.close();
}
} catch (Exception e) {
}
}
}
资源压缩包我已上传,若没有积分下载,可联系我留下邮箱。