使用 JID 来进行 Java 对象的高性能序列化

红薯 发布于 2013/02/26 14:19
阅读 4K+
收藏 76
JID

JID 是一个用来反序列化、更新和重新序列化 Map 对象,在 i5 2.53GHz 处理器的机器上,完成 10000 条目的操作仅需 4 毫秒。序列化和重新序列化的时间很大程度上依赖于表条目的大小和复杂度,增量式的序列化和反序列化用于达到高性能。

今天我试验了下使用 JID 进行 Java 对象的序列化过程,现将这个过程与大家分享,至于在何种场景下使用大家自己发挥。

首先 JID 依赖于 JActorSLF4J ,你下载的 JID 压缩包中就包含这二者的 jar 文件。

大家先不需要关心代码中牵扯的一些类是作何用途的,先把例子跑起来!

我们这里假设要对一个 User 对象进行序列化,User 对象如下:

/**
 * 序列化对象
 * @author Winter Lau
 */
public static class User extends AppJid {
	private StringJid getNameJid() throws Exception {
		return (StringJid) _iGet(0);
	}
	
	private IntegerJid getAgeJid() throws Exception {
		return (IntegerJid) _iGet(1);
	}
	
	public String getName() throws Exception {
		return getNameJid().getValue();
	}
	
	public void setName(String name) throws Exception {
		getNameJid().setValue(name);
	}
	
	public int getAge() throws Exception {
		return getAgeJid().getValue();
	}
	
	public void setAge(int age) throws Exception {
		getAgeJid().setValue(age);
	}
}
然后每个要做序列化的对象都需要有个对应的工厂类,这里是 UserFactory:
public static class UserFactory extends AppJidFactory {
	final public static UserFactory fac = new UserFactory();

	public UserFactory() {
		super("User", JidFactories.STRING_JID_TYPE, JidFactories.INTEGER_JID_TYPE);
	}

	protected User instantiateActor() throws Exception {
		return new User();
	}
}
其中特别注意 UserFactory 构造函数里的 "User" 这个参数,下面需要用到。

接下来就是测试程序:

public static void main(String[] args) throws Exception {
	
	JAFactory factory = new JAFactory(){{(new JidFactories()).initialize(this);}};
	factory.registerActorFactory(UserFactory.fac);
	
	RootJid rootJid = (RootJid) factory.newActor(JidFactories.ROOT_JID_TYPE);
	long ct = System.currentTimeMillis();
	rootJid.setValue("User");
	
	User user = (User)rootJid.getValue();
	user.setName("Winter Lau");
	user.setAge(98);
	
	int slen = rootJid.getSerializedLength();
	
	byte[] sdatas = new byte[slen];
	rootJid.save(sdatas, 0);
	
	rootJid.load(sdatas, 0, slen);
	User user1 = (User)rootJid.getValue();
	
	System.out.printf("%dms->%s:%d\n", (System.currentTimeMillis()-ct), user1.getName(), user1.getAge());
	
}

程序讲解:

1. 首先需要构造 JAFactory ,这是使用 JID 必须的一步(第3行)
2. 然后注册我们需要进行序列化的类(第4行)
3. 构造 RootJid,这也是必须的一步(第6行)
4. rootJid.setValue("User") 这是设置要进行序列化的对象类型,这个 "User" 就是我们在 UserFactory 定义的字符串
5. 对 User 对象实例进行值设置
6. 使用 rootJid.save 方法进行序列化,就是把对象转称 byte 数组
7. 最后一步是演示从 byte 数据中加载对象并打印对象的属性

这便是一个完整的使用 JID 进行自定义对象的序列化和反序列化的过程。如果你是使用 Java 原生的一些数据类型,就不需要自行创建类对象。

这里需要很注意的是 UserFactory 中构造函数的参数顺序,第一个参数是类型名称,接下来的每个参数是对应每个属性的类型,这个必须严格对应 User 类中的 _iGet(xx) 中 xx 的值。

据说 JID 的序列化的性能是极高的,这方面我还没进行测试。需要注意的是这个序列化的结果和 Java 本身的序列化是不兼容的。

完整的代码以及列表的序列化请看:

https://github.com/oschina/cache-framework/tree/master/src/net/oschina/demo

下一篇:使用 JFile 进行文件读写,一样很蛋疼。。。

加载中
0
红薯
红薯
比较蛋疼的是序列化对象必须扩展 AppJid 类!
Credo-Zhao
Credo-Zhao
的确..
假装是大神
假装是大神
对于以后的拓展或者移植,可以说是一种灾难。。。
0
猫哥-u
猫哥-u
看资料,写这个JA系列的老头子相当的厉害
麦田大圈圈
麦田大圈圈
回复 @红薯 : 这个老头以前的SUN公司的高级工程师,勤奋,有邮件必回
红薯
红薯
应该是 IBM 的,因为很多文档都直接指向 IBM 的网站地址
0
猫哥-u
猫哥-u

William E La Forge

A developer for 38 years, a research engineer and an Open Source Project Manager since 1998. Has worked for the Open Software Foundation (OSF) Research Institute, serving on a US Presidential commission, a DARPA Principal and CTO for JXML inc, a Staff Engineer at Sun Microsystems and as Director of Engineering at Fiorano. Current position is CTO of JActor Consulting Pvt.Ltd.

0
0
景愿
景愿
这个能不能叫超高度耦合
红薯
红薯
为了达到高性能所做的牺牲
0
0
空虚的人
空虚的人
这个以前看过,想用来着,结果必须基于jdk7,项目是6没办法了
0
dedenj
dedenj
拭目以待
0
xoHome
xoHome
这要有继承关系的类咋办
返回顶部
顶部