• Java序列化性能比较


    一、概述

    在很多论坛上都会谈论Java序列化,到底哪个很好呢?各有各的观点。这几天晚上正好在研究淘宝的dubbo的源代码,看到它写的一个测试用例,工程下载见:

    http://code.alibabatech.com/svn/dubbo/trunk/dubbo-common

    二、测试分析

    对同一个对象进行序列化:对象为long[] data = new long[] { -1l, 2l, 3l, 4l, 5l };

    java:aced0005757200025b4a782004b512b17593020000787000000005ffffffffffffffff0000000000000002000000000000000300000000000000040000000000000005:67

    compacted java:aced000575720000025b4a782004b512b17593020000787000000005ffffffffffffffff0000000000000002000000000000000300000000000000040000000000000005:68

    hessian:75055b6c6f6e67dfe2e3e4e5:12

    Dubbo:8585181b1c1d1e:7

    说明:对于小数据的序列化,Dubbo生成的字节是最小的,只有7个,而Java,Compacted Java是最大

    ,分别有67个和68个,序列化的结果越小,越适合rpc服务调用

    对同一个对象连续进行500次Write和Parse

    Dubbo:write and parse 500 times in 62ms, size 212

    Hessian2: write and parse 500 times in 516ms, size 378

    Java: write and parse 500 times in 203ms, size 969

    compacted java: write and parse 500 times in 109ms, size 596

    说明:和第一种的测试情况类似,dubbo的性能是最好的,花费的时间只共只有62ms,而大小只有212byte

    对一个超大对象进行一次的的Write和parse,如果细分的话,大概有100w个元素

    [reportprint]Dubbo write 1 times in 734ms, size 9600316

    [reportprint]Dubbo parse 1 times in 734ms, size 9600316

    [reportprint]Hessian2 write 1 times in 328ms, size 4100479

    [reportprint]Hessian2  parse 1 times in 563ms, size 4100479

    [reportprint]java write 1 times in 219ms, size 6800896

    [reportprint]java  parse 1 times in 172ms, size 6800896

    [reportprint]compacted java write 1 times in 188ms, size 6800474

    [reportprint] compacted java write and parse 1 times in 234ms, size 6800474

    说明:对于超大的数据,jdk自带的序列化性能最好,其次compacted java,Dubbo反而最差.

    三、测试代码

    /*
     * Copyright 1999-2011 Alibaba Group.
     *  
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *  
     *      http://www.apache.org/licenses/LICENSE-2.0
     *  
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.alibaba.dubbo.common.serialize;
    
    import static org.junit.Assert.assertEquals;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import org.junit.Test;
    
    import com.alibaba.com.caucho.hessian.io.Hessian2Input;
    import com.alibaba.com.caucho.hessian.io.Hessian2Output;
    import com.alibaba.dubbo.common.io.Bytes;
    import com.alibaba.dubbo.common.serialize.support.dubbo.Builder;
    import com.alibaba.dubbo.common.serialize.support.java.CompactedObjectInputStream;
    import com.alibaba.dubbo.common.serialize.support.java.CompactedObjectOutputStream;
    
    /**
     * @author qian.lei
     * @author ding.lid
     */
    public class SerializationCompareTest
    
    {
    	public void addBand(Band band, int loop) {
    		for (int i = 0; i < loop; i++) {
    			DataElement p = new DataElement();
    			p.setField("adafadsfasf");
    			p.setTitle("afdasf");
    			band.addChild(p);
    		}
    	}
    
    	public ReportPrint getReportPrint() {
    		int loop = 1000;
    		ReportPrint config = new ReportPrint();
    		addBand(config.getHeader(), 1);
    		addBand(config.getPageHeader(), 1);
    		addBand(config.getDetail(), loop * 100);// 有100行明细
    		addBand(config.getFooter(), 1);
    		return config;
    	}
    
    	@Test
    	public void test_CompareSerializeLength() throws Exception {
    		long[] data = new long[] { -1l, 2l, 3l, 4l, 5l };
    		ByteArrayOutputStream os;
    
    		os = new ByteArrayOutputStream();
    		ObjectOutputStream jos = new ObjectOutputStream(os);
    		jos.writeObject(data);
    		System.out.println("java:" + Bytes.bytes2hex(os.toByteArray()) + ":"
    				+ os.size());
    
    		os = new ByteArrayOutputStream();
    		CompactedObjectOutputStream oos = new CompactedObjectOutputStream(os);
    		oos.writeObject(data);
    		System.out.println("compacted java:"
    				+ Bytes.bytes2hex(os.toByteArray()) + ":" + os.size());
    
    		os = new ByteArrayOutputStream();
    		Hessian2Output h2o = new Hessian2Output(os);
    		h2o.writeObject(data);
    		h2o.flushBuffer();
    		System.out.println("hessian:" + Bytes.bytes2hex(os.toByteArray()) + ":"
    				+ os.size());
    
    		os = new ByteArrayOutputStream();
    		Builder<long[]> lb = Builder.register(long[].class);
    		lb.writeTo(data, os);
    		System.out.println("DataOutput:" + Bytes.bytes2hex(os.toByteArray())
    				+ ":" + os.size());
    	}
    
    	@Test
    	public void testBuilderPerm() throws Exception {
    		Builder<Bean> bb = Builder.register(Bean.class);
    		Bean bean = new Bean();
    		int len = 0;
    		long now = System.currentTimeMillis();
    		for (int i = 0; i < 500; i++) {
    			ByteArrayOutputStream os = new ByteArrayOutputStream();
    			bb.writeTo(bean, os);
    			os.close();
    			if (i == 0)
    				len = os.toByteArray().length;
    
    			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    			Bean b = bb.parseFrom(is);
    			assertEquals(b.getClass(), Bean.class);
    		}
    		System.out.println("Builder write and parse 500 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testH2oPerm() throws Exception {
    		Bean bean = new Bean();
    		int len = 0;
    		long now = System.currentTimeMillis();
    		for (int i = 0; i < 500; i++) {
    			ByteArrayOutputStream os = new ByteArrayOutputStream();
    			Hessian2Output out = new Hessian2Output(os);
    			out.writeObject(bean);
    			out.flushBuffer();
    			os.close();
    			if (i == 0)
    				len = os.toByteArray().length;
    			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    			Hessian2Input in = new Hessian2Input(is);
    			assertEquals(in.readObject().getClass(), Bean.class);
    		}
    		System.out.println("Hessian2 write and parse 500 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testJavaOutputPerm() throws Exception {
    		Bean bean = new Bean();
    		int len = 0;
    		long now = System.currentTimeMillis();
    		for (int i = 0; i < 500; i++) {
    			ByteArrayOutputStream os = new ByteArrayOutputStream();
    			ObjectOutputStream out = new ObjectOutputStream(os);
    			out.writeObject(bean);
    			os.close();
    			if (i == 0)
    				len = os.toByteArray().length;
    			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    			ObjectInputStream in = new ObjectInputStream(is);
    			assertEquals(in.readObject().getClass(), Bean.class);
    		}
    		System.out.println("java write and parse 500 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testCompactedJavaOutputPerm() throws Exception {
    		Bean bean = new Bean();
    		int len = 0;
    		long now = System.currentTimeMillis();
    		for (int i = 0; i < 500; i++) {
    			ByteArrayOutputStream os = new ByteArrayOutputStream();
    			CompactedObjectOutputStream out = new CompactedObjectOutputStream(
    					os);
    			out.writeObject(bean);
    			os.close();
    			if (i == 0)
    				len = os.toByteArray().length;
    			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    			CompactedObjectInputStream in = new CompactedObjectInputStream(is);
    			assertEquals(in.readObject().getClass(), Bean.class);
    		}
    		System.out.println("compacted java write and parse 500 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testBuilderPerm1() throws Exception {
    
    		Builder<ReportPrint> bb = Builder.register(ReportPrint.class);
    		ReportPrint bean = this.getReportPrint();
    		int len = 0;
    		long now = System.currentTimeMillis();
    
    		ByteArrayOutputStream os = new ByteArrayOutputStream();
    		bb.writeTo(bean, os);
    		os.close();
    
    		len = os.toByteArray().length;
    		System.out.println("[reportprint]Builder write 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    		now = System.currentTimeMillis();
    
    		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    		ReportPrint b = bb.parseFrom(is);
    		assertEquals(b.getClass(), ReportPrint.class);
    
    		System.out.println("[reportprint]Builder  parse 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testH2oPerm1() throws Exception {
    		ReportPrint bean = this.getReportPrint();
    
    		long now = System.currentTimeMillis();
    		ByteArrayOutputStream os = new ByteArrayOutputStream();
    		Hessian2Output out = new Hessian2Output(os);
    		out.writeObject(bean);
    		out.flushBuffer();
    		int len = os.toByteArray().length;
    		os.close();
    		System.out.println("[reportprint]Hessian2 write 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    		now = System.currentTimeMillis();
    		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    		Hessian2Input in = new Hessian2Input(is);
    		assertEquals(in.readObject().getClass(), ReportPrint.class);
    
    		System.out.println("[reportprint]Hessian2  parse 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testJavaOutputPerm1() throws Exception {
    		ReportPrint bean = this.getReportPrint();
    
    		long now = System.currentTimeMillis();
    
    		ByteArrayOutputStream os = new ByteArrayOutputStream();
    		ObjectOutputStream out = new ObjectOutputStream(os);
    		out.writeObject(bean);
    		int len = os.toByteArray().length;
    		os.close();
    		System.out.println("[reportprint]java write 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    		now = System.currentTimeMillis();
    		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    		ObjectInputStream in = new ObjectInputStream(is);
    		assertEquals(in.readObject().getClass(), ReportPrint.class);
    		System.out.println("[reportprint]java  parse 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    	}
    
    	@Test
    	public void testCompactedJavaOutputPerm1() throws Exception {
    		ReportPrint bean = this.getReportPrint();
    
    		long now = System.currentTimeMillis();
    
    		ByteArrayOutputStream os = new ByteArrayOutputStream();
    		CompactedObjectOutputStream out = new CompactedObjectOutputStream(os);
    		out.writeObject(bean);
    		int len = os.toByteArray().length;
    		os.close();
    		System.out.println("[reportprint]compacted write 1 times in "
    				+ (System.currentTimeMillis() - now) + "ms, size " + len);
    		now = System.currentTimeMillis();
    		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
    		CompactedObjectInputStream in = new CompactedObjectInputStream(is);
    		assertEquals(in.readObject().getClass(), ReportPrint.class);
    
    		System.out
    				.println("[reportprint]compacted  write and parse 1 times in "
    						+ (System.currentTimeMillis() - now) + "ms, size "
    						+ len);
    	}
    
    	public static enum EnumTest {
    		READ, WRITE, CREATE, UNREGISTER
    	};
    
    	static class MyList<T> extends ArrayList<T> {
    		private static final long serialVersionUID = 1L;
    
    		private int code = 12345;
    		private String id = "feedback";
    	}
    
    	static class MyMap<K, V> extends HashMap<K, V> {
    		private static final long serialVersionUID = 1L;
    
    		private int code = 12345;
    		private String id = "feedback";
    	}
    
    	public static class Bean implements Serializable {
    		private static final long serialVersionUID = 7737610585231102146L;
    
    		public EnumTest ve = EnumTest.CREATE;
    
    		public int vi = 0;
    		public long vl = 100l;
    
    		boolean b = true;
    		boolean[] bs = { false, true };
    
    		String s1 = "1234567890";
    		String s2 = "1234567890一二三四五六七八九零";
    
    		int i = 123123, ni = -12344, is[] = { 1, 2, 3, 4, -1, -2, -3, -4 };
    		short s = 12, ns = -76;
    		double d = 12.345, nd = -12.345;
    		long l = 1281447759383l, nl = -13445l;
    		private ArrayList<Object> mylist = new ArrayList<Object>();
    		{
    			mylist.add(1);
    			mylist.add("qianlei");
    			mylist.add("qianlei");
    			mylist.add("qianlei");
    			mylist.add("qianlei");
    		}
    		private HashMap<Object, Object> mymap = new HashMap<Object, Object>();
    		{
    			mymap.put(1, 2);
    			mymap.put(2, "1234");
    			mymap.put("2345", 12938.122);
    			mymap.put("2345", -1);
    			mymap.put("2345", -1.20);
    		}
    
    		public ArrayList<Object> getMylist() {
    			return mylist;
    		}
    
    		public void setMylist(ArrayList<Object> list) {
    			mylist = list;
    		}
    
    		public HashMap<Object, Object> getMymap() {
    			return mymap;
    		}
    
    		public void setMymap(HashMap<Object, Object> map) {
    			mymap = map;
    		}
    	}
    }
    
    本博客均为原创,转载请注明出处.
  • 相关阅读:
    解决VS2005 远程工具无法通过同步软件连接S5pv210 样机的问题
    java.util.concurrent 多线程框架线程池编程(三)
    线程池java.util.concurrent 多线程框架(二)
    java.util.concurrent 多线程框架线程池编程(一)
    java.util.concurrent 多线程框架线程池编程(四)
    Box2D学习笔记(2)
    Box2D学习笔记(1)
    ASP.NET页面防止刷新
    C#中跨数据库增删改的事务控制
    .NET(C#)开源代码分析
  • 原文地址:https://www.cnblogs.com/mzhanker/p/2232279.html
Copyright © 2020-2023  润新知