天天看點

json-lib 與Jackson性能對比

由于打算采用redis緩存接收到的資料,而接收到的資料解析後的結果是一個Map,希望利用redis緩存該Map,而redis中能接收的資料類型為String與byte數組,考慮再三,決定采用String存儲,對于Map轉String存儲,以及反轉,我首先想到的是json字元串的方式存儲(雖然後來與一位朋友溝通後表示google的protobuf可能性能與記憶體占用上可能更佳),下面是測試結果:

Map大小為13,占1548個位元組,單線程轉換10000次,并反轉,結果如下:

----------json-lib---------------
Map轉字元串耗時:5540.254697
字元串轉Map耗時:14268.4411
--------Jackson------------------
Map轉字元串耗時:962.843043
字元串轉Map耗時:530.927814


   
    

         

以下為測試代碼:

MapToJson.java

package com.json.test;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import com.fasterxml.jackson.databind.ObjectMapper;

public class MapToJson {
	/**
	 * 模拟的OBD資料上報(10資料+3基站)
	 */
	public static Map<String,Object> obdDataMap;
	public static List<String> obdDataList = new ArrayList<String>();
	public static ObjectMapper mapper = new ObjectMapper();
	
	public static int COUNT = 10000;
	
	public static JsonConfig jsonConfig;  
	static{
		init();
		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(java.util.Date.class, new JsonDateValueProcessor());  
        jsonConfig.registerJsonValueProcessor(java.sql.Date.class, new JsonDateValueProcessor());  
	}
	static void init(){
		obdDataMap = new HashMap<String, Object>();
		List<Map<String,Object>> dataList = new ArrayList<Map<String,Object>>();
		Map<String,Object> dataMap = null;
		Map<String,Object> obdMap = null;
		for(int i=0;i<10;i++){
			dataMap = new HashMap<String, Object>();
			obdMap = new HashMap<String,Object>();
			obdMap.put("GATHERTIME", new Date());
			obdMap.put("PID_010B", 43);
			obdMap.put("PID_010C", 784.25d);
			obdMap.put("OBD_SPEED", 12);
			obdMap.put("PID_010F", 53);
			dataMap.put("obdData", obdMap);
			dataList.add(dataMap);
		}
		for(int i=0;i<3;i++){
			dataMap = new HashMap<String, Object>();
			obdMap = new HashMap<String,Object>();
			obdMap.put("CELL_ID", "22253");
			obdMap.put("MOBILE_COUNTRY_CODE", "460");
			obdMap.put("LOCATION_AREA_CODE", "22528");
			obdMap.put("MOBILE_NETWORK_CODE", "0");
			obdMap.put("SIGNAL_STRENGTH", "38");
			dataMap.put("cellTowerData", obdMap);
			dataList.add(dataMap);
		}
		
		obdDataMap.put("sourceData", dataList);
	}
	
	public static void mapToStr(){
		long t0 = System.nanoTime();
		JSONObject json = null;
		for(int i=0;i<COUNT;i++){	//10000
			json = JSONObject.fromObject(obdDataMap,jsonConfig);
			obdDataList.add(json.toString());
//			System.out.println(json.toString().length());
		}
		
		long t1 = System.nanoTime();
		System.out.println("Map轉字元串耗時:"+(t1-t0)/1000000.0);
	}
	public static void mapToStr2() throws IOException{
		long t0 = System.nanoTime();
		String str = null;
		for(int i =0;i<COUNT;i++){
			str = mapper.writeValueAsString(obdDataMap);
			obdDataList.add(str);
//			System.out.println(str);
		}
		long t1 = System.nanoTime();
		System.out.println("Map轉字元串耗時:"+(t1-t0)/1000000.0);
	}
	
	public static void strToMap(){
		long t0 = System.nanoTime();
		List<JSONObject> jsonArray = JSONArray.fromObject(obdDataList,jsonConfig);
		Map<String,Object> map;
		for(JSONObject obj:jsonArray){
			map = (Map<String, Object>) obj;
//			System.out.println(map);
		}
		long t1 = System.nanoTime();
		System.out.println("字元串轉Map耗時:"+(t1-t0)/1000000.0);
	}
	
	public static void strToMap2() throws IOException{
		long t0 = System.nanoTime();
		Map<String,Object> map = null;
		for(String str:obdDataList){
			map = mapper.readValue(str, Map.class);
//			System.out.println(map);
		}
		long t1 = System.nanoTime();
		System.out.println("字元串轉Map耗時:"+(t1-t0)/1000000.0);
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		System.out.println("----------json-lib---------------");
		mapToStr();
		strToMap();
		obdDataList.clear();
		System.out.println("--------Jackson------------------");
		mapToStr2();
		strToMap2();
	}

}


   
    

         

一個輔助類  JsonDateValueProcessor.java

package com.json.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

/****************************************************************************
 * com.sides.pub.util JsonDateValueProcessor.java Created on 2013-9-16
 * @Author: linfenliang
 * @Description: 該類主要将日期類型(java.util.Date與java.sql.Date)格式化為yyyy-MM-dd HH:mm:ss字元串
 * @Version: 1.0
 ***************************************************************************/
public class JsonDateValueProcessor implements JsonValueProcessor {
	private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
	/**
	 * 将日期類型(java.util.Date與java.sql.Date)格式化為yyyy-MM-dd HH:mm:ss字元串
	 * @author linfenliang	
	 */
	public JsonDateValueProcessor() {  
	        super();  
	    }  
	
	@Override
	public Object processArrayValue(Object arg0, JsonConfig arg1) {
		return process(arg0);  
	}

	@Override
	public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {
		return process(arg1);
	}
	private Object process(Object value) {  
        try {  
            if (value instanceof java.util.Date || value instanceof java.sql.Date) {  
                return dateFormat.format(value);  
            }  
            return value == null ? "" : value.toString();  
        } catch (Exception e) {  
            return "";  
        }  
    }  
}