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

简介

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

  • 专门针对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原生序列化性能十几倍

 

posted @ 2017-01-22 21:58  坏~牧羊人  阅读(25984)  评论(2编辑  收藏  举报