fastjson与jackson的性能比较

本文仅作客观比较fastjson与jackson的性能测试,部分测试代码引自http://www.oschina.net/code/snippet_1156226_26432#44097 文中的方法,但是纠正了对于jackson的使用方式(需要写成单例先初始化,不要每次都new)。分别测试序列化1000,1万与10万次数据所花费的时间。

当然在此,如果大家发现文中的使用错误,也希望随时指出来帮助大家将优化做的更好。

测试代码均使用最新的jar包,而具体版本如下:

Jackson 2.x:

(这里仅测试Jackson2.x因为和1.x相比还是有些变化的,从包名就可以发现2.x变成com.fasterxml.jackson而不是1.x的org.codehaus.jackson希望大家注意区分)

jackson-annotations-2.4.1.jar

jackson-core-2.4.1.jar

jackson-databind-2.4.1.jar

fastjson

fastjson-1.1.41.jar

======================================================

------------------------------------以下为测试结果------------------------------

======================================================

预置条件1:循环1000次。

============序列化===========

序列化生成数据所用时间(秒):0.12

序列化Jackson所用时间(秒):0.077

序列化fastjson所用时间(秒):0.07

===========反序列化===========

反序列化生成数据所用时间(秒):0.095

反序列化Jackson所用时间(秒):0.114

反序列化fastjson所用时间(秒):0.149

-------------------------------------------------------------------------------------

预置条件2:循环10000次。

============序列化===========

序列化生成数据所用时间(秒):0.289

序列化Jackson所用时间(秒):0.281

序列化fastjson所用时间(秒):0.277

===========反序列化===========

反序列化生成数据所用时间(秒):0.344

反序列化Jackson所用时间(秒):0.416

反序列化fastjson所用时间(秒):0.445

-------------------------------------------------------------------------------------

预置条件3:循环100000次。

============序列化===========

序列化生成数据所用时间(秒):1.99

序列化Jackson所用时间(秒):0.855

序列化fastjson所用时间(秒):1.774

===========反序列化===========

反序列化生成数据所用时间(秒):2.69

反序列化Jackson所用时间(秒):1.33

反序列化fastjson所用时间(秒):1.606

以上对于10万条数据的测试可以看出jackson2.x在序列化上确实显现出了一些优势。

以下附代码(并附件打包):

/**
 * 主测试类
 */
package com.test;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;

/**
 *
 * @author guoyongxiang
 * Date: 2014-8-20
 */
public class JsonParseTest {
	
	public static void main(String[] args) throws IOException {
        System.out.println("============序列化===========");
        Monitoring.begin();
        List<Corp> list = new ArrayList<Corp>();
        for (int i = 0; i < 100000; i++) {
            list.add(fullObject(Corp.class));
        }
        Monitoring.end("序列化生成数据");
        
        // 排除首次初始化差异
        JacksonMapper.toJson(list.get(0));
        Monitoring.begin();
        jacksonSerialize(list);
        Monitoring.end("序列化Jackson");
        
        // 排除首次初始化差异
        JSON.toJSONString(list.get(0));
        Monitoring.begin();
        fastjsonSerialize(list);
        Monitoring.end("序列化fastjson");
        
        
        System.out.println("===========反序列化===========");
        
        List<String> jsonStrList = new ArrayList<String>();
        for (Corp corp : list) {
            String str = JacksonMapper.toJson(corp);
            jsonStrList.add(str);
        }
        Monitoring.end("反序列化生成数据");
        
        // 排除首次初始化差异
    	JacksonMapper.toObj(jsonStrList.get(0), Corp.class);
        Monitoring.begin();
        jacksonUnSerialize(jsonStrList);
        Monitoring.end("反序列化Jackson");
 
        // 排除首次初始化差异
        JSON.parseObject(jsonStrList.get(0), Corp.class);
        Monitoring.begin();
        fastjsonUnSerialize(jsonStrList);
        Monitoring.end("反序列化fastjson");
        
    }
	// ---------------------------------序列化---------------------------------
    public static void jacksonSerialize(List<Corp> list) throws JsonProcessingException {
        for (Corp corp : list) {
            String str = JacksonMapper.toJson(corp);
        }
    }
    
    public static void fastjsonSerialize(List<Corp> list) {
    	for (Corp corp : list) {
    		String str = JSON.toJSONString(corp);
    	}
    }
    // ---------------------------------反序列化---------------------------------
    public static void jacksonUnSerialize(List<String> list) throws IOException {
        for (String json : list) {
        	Corp corp = JacksonMapper.toObj(json, Corp.class);
        }
    }
 
    public static void fastjsonUnSerialize(List<String> list) {
    	for (String json : list) {
    		Corp corp = JSON.parseObject(json, Corp.class);
    	}
    }
    
    /**
     * 填充一个对象(一般用于测试)
     */
    public static <T> T fullObject(Class<T> cl) {
        T t = null;
        try {
            t = cl.newInstance();
            Method methods[] = cl.getMethods();
            for (Method method : methods) {
                // 如果是set方法,进行随机数据的填充
                if (method.getName().indexOf("set") == 0) {
                    Class<?> param = method.getParameterTypes()[0];
                    if (param.equals(String.class)) {
                        method.invoke(t, getRandomString(5));
                    } else if (param.equals(Short.class)) {
                        method.invoke(t, (short) new Random().nextInt(5));
                    } else if (param.equals(Float.class)) {
                        method.invoke(t, new Random().nextFloat());
                    } else if (param.equals(Double.class)) {
                        method.invoke(t, new Random().nextDouble());
                    } else if (param.equals(Integer.class)) {
                        method.invoke(t, new Random().nextInt(10));
                    } else if (param.equals(Long.class)) {
                        method.invoke(t, new Random().nextLong());
                    } else if (param.equals(Date.class)) {
                        method.invoke(t, new Date());
                    } else if (param.equals(Timestamp.class)) {
                        method.invoke(t, new Timestamp(System.currentTimeMillis()));
                    } else if (param.equals(java.sql.Date.class)) {
                        method.invoke(t, new java.sql.Date(System.currentTimeMillis()));
                    }
                }
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return t;
    }
    
    public static String getRandomString(int length) { //length表示生成字符串的长度
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";   //生成字符串从此序列中取
        Random random = new Random();   
        StringBuffer sb = new StringBuffer();   
        for (int i = 0; i < length; i++) {   
            int number = random.nextInt(base.length());   
            sb.append(base.charAt(number));   
        }   
        return sb.toString();   
     }
}

计时器:

/**
 * 
 */
package com.test;

/**
 * 计时器
 * @author guoyongxiang
 * Date: 2014-8-20
 */
public class Monitoring {
	private static ThreadLocal<Long> begin = new ThreadLocal<Long>();
	 
    public static void begin() {
        begin.set(System.currentTimeMillis());
    }
 
    public static void end(String name) {
        double time = (System.currentTimeMillis() - begin.get()) / 1000.0;
        System.out.println(name + "所用时间(秒):" + time);
    }
}

测试对象

/**
 * 
 */
package com.test;

import java.sql.Timestamp;


/**
 * 对象
 * @author guoyongxiang
 * Date: 2014-8-20
 */
public class Corp {
	private Long uid;
    private Integer corpGrade;
    private Integer cityId;
    private String name;
    private String EName;
    private String description;
    private String zipCode;
    private String tel;
    private String fax;
    private String EMail;
    private Integer isEmailOpen;
    private Integer EMailChecked;
    private Timestamp regDateOnGov;
    private String backroll;
    private String address;
    private String webStoreUrl;
    private Integer isNew;
    private Integer credit;
    private Integer activeDegrees;
    private Integer hits;
    private Integer isHitsRecord;
    private Timestamp regTimeOnZfa;
    private Integer corpType;
    private Integer corpMajorcategoryId;
    private Integer businessRoleId;
    private String keyword;
    private Integer developState;
    private String isAlert;
    private Integer advMemState;
    private Integer advStockState;
    private Integer allianceState;
    private Timestamp lastUpdateTime;
    private Integer corpMajorcategoryId1;
    private String keyword1;
    private Long certificatePic;
    private Integer isUpdateCharter;
    private Integer currcount;
    private Integer curronsale;
    private Integer curronhot;
    private Integer currniccount;
    private Integer currniconsale;
    private Integer currniconhot;
    private String buyProducts;
    private Integer isOpenShop;
    private Integer state;
    private String mainProduct;
    private String advBrandIds;
    private String feature;
    private Integer category;
    private Integer contactFlag;
    private String fastPassage;
	
    // 省略getter/setter
}

jackson 工具类(默认设置,过多设置会降低效率而且很明显,如识别json中的单引号等)

package com.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 *  JacksonMapper
 *
 *  @author guoyongxiang
 */
public class JacksonMapper {

	private static final ObjectMapper mapper = new ObjectMapper();

	private JacksonMapper() {
	}

	public static ObjectMapper getInstance() {
		return mapper;
	}

	/**
	 * Object to Json String
	 * 
	 * @param obj
	 * @return
	 * @throws JsonProcessingException 
	 */
	public static String toJson(Object obj) throws JsonProcessingException {

		ObjectMapper mapper = JacksonMapper.getInstance();
		//SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); 
		//mapper.setDateFormat(df);
		return mapper.writeValueAsString(obj);
	}

	/**
	 * Json to List
	 * 
	 * @param <T>
	 * @param json
	 * @param clazz
	 * @return
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonParseException 
	 */
	public static <T> List<T> toList(String json, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
		ObjectMapper mapper = JacksonMapper.getInstance();
		//mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
		//mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
		List<T> list = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz));
		return list;
	}

	/**
	 * Json String to Object<br>
	 * String json = "..."; ObjectMapper mapper = JacksonMapper.getInstance();<br>
	 * YourBean bean = mapper.readValue(json, new YourBean().getClass());
	 * 
	 * @param json
	 * @param clazz
	 * @return 
	 * @throws IOException 
	 * @throws JsonMappingException 
	 * @throws JsonParseException 
	 */
	public static <T> T toObj(String json, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException{
		ObjectMapper mapper = JacksonMapper.getInstance();
		//mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
		//mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
		return mapper.readValue(json, clazz);
	}
	
	/**
	 * JsonNode to Object
	 * @param node
	 * @param clazz
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static <T> T toObj(JsonNode node, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException{
		ObjectMapper mapper = JacksonMapper.getInstance();
		return mapper.readValue(node.toString(), clazz);
	}
	
	/**
	 * Json String to JsonNode
	 * @param json
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	public static JsonNode toNode(String json) throws JsonProcessingException, IOException{
		ObjectMapper mapper = JacksonMapper.getInstance();
		return mapper.readTree(json);
	}
	
	/**
	 * Object to JsonNode
	 * @param obj
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	public static JsonNode toNode(Object obj) throws JsonProcessingException, IOException{
		String json = toJson(obj);
		return toNode(json);
	}
}

相关推荐