博文首次發佈於安卓巴士,現搬於CSDN之上
寫博客不易,珍惜筆者勞動成果,轉載請標明原創作者地址 http://blog.csdn.net/zml_2015/article/details/52165317
今天無意中再安卓巴士上看到了一片文章《Android開發者應該使用FlatBuffers替代JSON》,嚇得我趕緊看了看,突然感覺自己用了好長時間的JSON解析似乎落伍了~~(>_<)~~
尤其是看到下面的話,更是不明覺厲;
我嘗試使用FlatBuffers和JSON解析4mb的JSON文件。
FlatBuffers花了1-5ms,JSON花了大約2000ms。在使用FlatBuffers期間Android App中沒有GC,而在使用JSON時發生了很多次GC
- 大致看了一下FlatBuffers,似乎挺強大,不過暫時沒有測試是不是真有那麼快,不過JSON解析應該沒有那麼慢,於是乎測試了一下平時用到的谷歌的Gson 阿里巴巴的FastJson以及安卓原生自帶的org.JSON 解析的速度;
- 先寫個單元測試吧:
@org.junit.Test
public void TestSpeed2() throws Exception {
FoodDao foodDao = new FoodDao();
List<Foods> foods = foodDao.selectAll(Foods.class);
System.out.println("-------------gson-----------");
long gsonStart = System.currentTimeMillis();
gsonC(foods);// 用Gson進行拆包 和 解析
long gsonEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (gsonEnd - gsonStart));
System.out.println("-------------gson-----------");
System.out.println("-------------FastJson-----------");
long fastStart = System.currentTimeMillis();
fastJsonC(foods);// 用FastJson進行拆包 和 解析
long fastEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (fastEnd - fastStart));
System.out.println("-------------FastJson-----------");
System.out.println("-------------JSON-----------");
long jsonStart = System.currentTimeMillis();
jsonC(foods);// 用org.json進行拆包 和 解析
long jsonEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (jsonEnd - jsonStart));
System.out.println("-------------JSON-----------");
}
- 調用的方法必須是
synchronized 同步
的,即運行完該方法後才執行下面的代碼
private synchronized void jsonC(List<Foods> foods) throws Exception {
String jsonString = JsonTools.createJsonString("json", foods);
JSONObject object = new JSONObject(jsonString);
JSONArray array = object.getJSONArray("json");
List<Foods> list2 = new ArrayList<Foods>();
for (int i = 0; i < array.length(); i++) {
JSONObject foodObject = (JSONObject) array.get(i);
Foods foods2 = new Foods(foodObject.getInt("id"),
foodObject.getString("cookclass"),
foodObject.getString("name"),
foodObject.getString("description"),
foodObject.getString("food"),
foodObject.getString("img"),
foodObject.getString("images"),
foodObject.getString("keywords"),
foodObject.getString("message"),
foodObject.getString("url"));
list2.add(foods2);
}
String s3 = list2.toString();
}
private synchronized void fastJsonC(List<Foods> foods) {
String fastString = FastJsonTools.createJsonString(foods);
String s2 = FastJsonTools.createJsonToListBean(fastString,
Foods.class).toString();
}
private synchronized void gsonC(List<Foods> foods) {
String gsonString = GsonTools.createJsonString(foods);
String s1 = GsonTools.StringTolist(gsonString, Foods[].class)
.toString();
}
- 單元測試中調用了一個selectAll方法,具體如下:
/**
* 查找全部;
*
* @return
*/
public List selectAll(Class c) {
Session session = HibernateSessionFactory.getSession();
List list = session.createQuery("From " + c.getName()).setFirstResult(0).setMaxResults(50).list();//①
return list;
}
- 查看上面的標註①的地方可以看到我這先設置的查詢的條數爲50條,稍後修改這即可更改爲查詢100、500、1000、5000、1萬、2萬條
(不要問我哪兒來那麼多數據……我之前寫的博客上說了曾經扒到過10W+的數據……)
然後列一下分別是查詢50條、100條、500條、1000、5000、1萬、2萬條數據各個類庫分別需要多少時間
- 50
2. 100
3. 500
4. 1000
5. 5000
6. 1萬
7. 2萬
- 一開始測試的時候我沒有取平均值,只是運行一下看看解析50條數據哪一個更快一點,竟然讓我出乎意料,竟然是Android自帶的jar包org.JSON!!!Gson甚至比FastJson都快這不符合情理啊……不是一直都說是阿里巴巴的FastJson最快的嘛!!!!後來我將解析50條數據提高到100、500、1000條……數據的時候就發現,隨着解析數據量的增大然後逐漸的發現FastJson的優勢出來了,而org.JSON卻很慢了
- 分析出現上面的結果的原因,爲什麼在數據量少的時候,org.json 類庫拆包解析的更快呢,仔細看源碼會發現:
org.json在進行解析的時候需要通過for循環依次的將數據取出來放到指定對象的成員變量中
是for循環的緣故,當for循環的次數太多的時候肯定就相當耗時了,在數據量小的時候卻表現的比較出色 - 然而這樣解析有着明顯的問題,因爲每一次測試的時間都不相同,因爲不是很穩定,所以應該取一下平均值,我這就對 拆包解析的方法里加了個50次的循環
@org.junit.Test
public void TestSpeed() throws Exception {
List<Foods> foods = foodDao.selectAll(Foods.class);
System.out.println("-------------gson-----------");
long gsonStart = System.currentTimeMillis();
gsonC(foods);//用Gson進行拆包 和 解析 並循環操作50次
long gsonEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (gsonEnd - gsonStart) / 50);
System.out.println("-------------gson-----------");
System.out.println("-------------FastJson-----------");
long fastStart = System.currentTimeMillis();
fastJsonC(foods);// 用FastJson進行拆包 和 解析 並循環操作50次
long fastEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (fastEnd - fastStart) / 50);
System.out.println("-------------FastJson-----------");
System.out.println("-------------JSON-----------");
long jsonStart = System.currentTimeMillis();
jsonC(foods);// 用org.json進行拆包 和 解析 並循環操作50次
long jsonEnd = System.currentTimeMillis();
System.out.println("gsonGaps:" + (jsonEnd - jsonStart) / 50);
System.out.println("-------------JSON-----------");
}
private synchronized void jsonC(List<Foods> foods) throws Exception {
for (int j = 0; j < 50; j++) {
String jsonString = JsonTools.createJsonString("json", foods);
JSONObject object = new JSONObject(jsonString);
JSONArray array = object.getJSONArray("json");
List<Foods> list2 = new ArrayList<Foods>();
for (int i = 0; i < array.length(); i++) {
JSONObject foodObject = (JSONObject) array.get(i);
Foods foods2 = new Foods(foodObject.getInt("id"),
foodObject.getString("cookclass"),
foodObject.getString("name"),
foodObject.getString("description"),
foodObject.getString("food"),
foodObject.getString("img"),
foodObject.getString("images"),
foodObject.getString("keywords"),
foodObject.getString("message"),
foodObject.getString("url"));
list2.add(foods2);
}
String s3 = list2.toString();
}
}
private synchronized void fastJsonC(List<Foods> foods) {
for (int i = 0; i < 50; i++) {
String fastString = FastJsonTools.createJsonString(foods);
String s2 = FastJsonTools.createJsonToListBean(fastString,
Foods.class).toString();
}
}
private synchronized void gsonC(List<Foods> foods) {
for (int i = 0; i < 50; i++) {
String gsonString = GsonTools.createJsonString(foods);
String s1 = GsonTools.StringTolist(gsonString, Foods[].class)
.toString();
}
}
然後貼一下解析
1萬條數據
、2萬條數據
和100條數據
各個類庫所用的的平均時間(這個時間不包括查詢數據庫所用的時間)1萬
2萬
100條
我10萬+的數據大概是40多M,也就是說1萬條數據的話大概是4M,就從我的測試結果來看,還真不知道他們那個解析4Mjson數據需要用大概2000毫秒的時間,我測試的2萬條數據也就是大概8M的json數據,即使是用org.json來拆包、解析都要比這個時間要短很多,更何況我們還有出色的fastJson等優秀類庫。
經過這次測試之後,確實驗證了阿里巴巴的FastJson相對來說是挺快的,如果用json解析的話,還是建議用fastjson吧