java原生序列化和Kryo序列化性能比较

时间:2022-10-15 07:32:49

简介

最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括:

  • 专门针对Java语言的:Kryo,FST等等
  • 跨语言的:Protostuff,ProtoBuf,Thrift,Avro,MsgPack等等

这些序列化方式的性能多数都显著优于hessian2(甚至包括尚未成熟的dubbo序列化)。有鉴于此,我们为dubbo引入Kryo和FST这 两种高效Java序列化实现,来逐步取代hessian2。其中,Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、 Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。而FST是一种较新的序列化实现,目前还缺乏足够多的成熟使用案例,但它还是非 常有前途的,下面我们比较下,java原生序列化Kryo序列化性能比较

1、实体类 Simple.java

package bhz.entity;

import java.io.Serializable;
import java.util.Map;

public class Simple implements Serializable
{
private static final long serialVersionUID = -4914434736682797743L;
private String name;
private int age;
private Map<String,Integer> map;
public Simple(){

}
public Simple(String name,int age,Map<String,Integer> map){
this.name = name;
this.age = age;
this.map = map;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Map<String, Integer> getMap() {
return map;
}

public void setMap(Map<String, Integer> map) {
this.map = map;
}


}

2、java原生序列化 OriginalSerializable.java

package bhz.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;

import bhz.entity.Simple;

public class OriginalSerializable {

public static void main(String[] args) throws IOException, ClassNotFoundException {
long start = System.currentTimeMillis();
setSerializableObject();
System.out.println("java原生序列化时间:" + (System.currentTimeMillis() - start) + " ms" );  

start
= System.currentTimeMillis();
getSerializableObject();
System.out.println("java原生反序列化时间:" + (System.currentTimeMillis() - start) + " ms");

}

public static void setSerializableObject() throws IOException{

FileOutputStream fo
= new FileOutputStream("D:/file2.bin");

ObjectOutputStream so
= new ObjectOutputStream(fo);

for (int i = 0; i < 100000; i++) {
Map
<String,Integer> map = new HashMap<String, Integer>(2);
map.put(
"zhang0", i);
map.put(
"zhang1", i);
so.writeObject(
new Simple("zhang"+i,(i+1),map));
}
so.flush();
so.close();
}

public static void getSerializableObject(){
FileInputStream fi;
try {
fi
= new FileInputStream("D:/file2.bin");
ObjectInputStream si
= new ObjectInputStream(fi);

Simple simple
=null;
while((simple=(Simple)si.readObject()) != null){
//System.out.println(simple.getAge() + " " + simple.getName());
}
fi.close();
si.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
//e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

}

3、kyro序列化 KyroSerializable.java

package bhz.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.objenesis.strategy.StdInstantiatorStrategy;

import bhz.entity.Simple;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

public class KyroSerializable {

public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
setSerializableObject();
System.out.println(
"Kryo 序列化时间:" + (System.currentTimeMillis() - start) + " ms" );
start
= System.currentTimeMillis();
getSerializableObject();
System.out.println(
"Kryo 反序列化时间:" + (System.currentTimeMillis() - start) + " ms");

}

public static void setSerializableObject() throws FileNotFoundException{

Kryo kryo
= new Kryo();
kryo.setReferences(
false);
kryo.setRegistrationRequired(
false);
kryo.setInstantiatorStrategy(
new StdInstantiatorStrategy());
kryo.register(Simple.
class);
Output output
= new Output(new FileOutputStream("D:/file1.bin"));
for (int i = 0; i < 100000; i++) {
Map
<String,Integer> map = new HashMap<String, Integer>(2);
map.put(
"zhang0", i);
map.put(
"zhang1", i);
kryo.writeObject(output,
new Simple("zhang"+i,(i+1),map));
}
output.flush();
output.close();
}


public static void getSerializableObject(){
Kryo kryo
= new Kryo();
kryo.setReferences(
false);
kryo.setRegistrationRequired(
false);
kryo.setInstantiatorStrategy(
new StdInstantiatorStrategy());
Input input;
try {
input
= new Input(new FileInputStream("D:/file1.bin"));
Simple simple
=null;
while((simple=kryo.readObject(input, Simple.class)) != null){
//System.out.println(simple.getAge() + " " + simple.getName() + " " + simple.getMap().toString());
}

input.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(KryoException e){

}
}

}

4、测试结果对比

java原生序列化时间:8281 ms
java原生反序列化时间:5899 ms

Kryo 序列化时间:630 ms
Kryo 反序列化时间:15 ms

经过对比,可以发现kryo是java原生序列化性能十几倍