吾勇士

Gson、FastJson、org.JSON到底哪一个效率更高,速度更快

Gson、FastJson、org.JSON到底哪一个效率更高,速度更快

写博客不易,珍惜笔者劳动成果,转载请标明原创作者地址 http://www.apkbus.com/blog-725636-61364.html?_dsign=d1a2c39f

今天无意中再安卓巴士上看到了一片文章《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 解析的速度;
  • 先写个单元测试吧:
/**

  • @author 郑明亮

  • @Time:2016年8月9日 下午6:31:19

  • @version 1.0
    */<code class="java" data-origin="<pre><code class="java">@org.junit.Test
    public void TestSpeed2() throws Exception {
    FoodDao foodDao = new FoodDao();
    List&lt;Foods&gt; foods = foodDao.selectAll(Foods.class);

     System.out.println(&quot;-------------gson-----------&quot;);
     long gsonStart = System.currentTimeMillis();
     gsonC(foods);// 用Gson进行拆包 和 解析
     long gsonEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (gsonEnd - gsonStart));
     System.out.println(&quot;-------------gson-----------&quot;);
    
     System.out.println(&quot;-------------FastJson-----------&quot;);
     long fastStart = System.currentTimeMillis();
     fastJsonC(foods);// 用FastJson进行拆包 和 解析
     long fastEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (fastEnd - fastStart));
     System.out.println(&quot;-------------FastJson-----------&quot;);
    
     System.out.println(&quot;-------------JSON-----------&quot;);
     long jsonStart = System.currentTimeMillis();
     jsonC(foods);// 用org.json进行拆包 和 解析
     long jsonEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (jsonEnd - jsonStart));
     System.out.println(&quot;-------------JSON-----------&quot;);
    

    }
    </code></pre>">@org.junit.Test
    public void TestSpeed2() throws Exception
    {
    FoodDao foodDao = new FoodDao();
    List<Foods> foods = foodDao.selectAll(Foods.class);

     System.out.println(<span class="hljs-string">"-------------gson-----------"</span>);
     <span class="hljs-keyword">long</span> gsonStart = System.currentTimeMillis();
     gsonC(foods);<span class="hljs-comment">// 用Gson进行拆包 和 解析</span>
     <span class="hljs-keyword">long</span> gsonEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (gsonEnd - gsonStart));
     System.out.println(<span class="hljs-string">"-------------gson-----------"</span>);
    
     System.out.println(<span class="hljs-string">"-------------FastJson-----------"</span>);
     <span class="hljs-keyword">long</span> fastStart = System.currentTimeMillis();
     fastJsonC(foods);<span class="hljs-comment">// 用FastJson进行拆包 和 解析</span>
     <span class="hljs-keyword">long</span> fastEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (fastEnd - fastStart));
     System.out.println(<span class="hljs-string">"-------------FastJson-----------"</span>);
    
     System.out.println(<span class="hljs-string">"-------------JSON-----------"</span>);
     <span class="hljs-keyword">long</span> jsonStart = System.currentTimeMillis();
     jsonC(foods);<span class="hljs-comment">// 用org.json进行拆包 和 解析</span>
     <span class="hljs-keyword">long</span> jsonEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (jsonEnd - jsonStart));
     System.out.println(<span class="hljs-string">"-------------JSON-----------"</span>);
    

    }

  • 调用的方法必须是 synchronized 同步的,即运行完该方法后才执行下面的代码
private synchronized void jsonC(List<Foods> foods) throws Exception {

        String jsonString = JsonTools.createJsonString(<span class="hljs-string">"json"</span>, foods);
        JSONObject object = <span class="hljs-keyword">new</span> JSONObject(jsonString);
        JSONArray array = object.getJSONArray(<span class="hljs-string">"json"</span>);
        List&lt;Foods&gt; list2 = <span class="hljs-keyword">new</span> ArrayList&lt;Foods&gt;();
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; array.length(); i++) {

            JSONObject foodObject = (JSONObject) array.get(i);
            Foods foods2 = <span class="hljs-keyword">new</span> Foods(foodObject.getInt(<span class="hljs-string">"id"</span>),
                    foodObject.getString(<span class="hljs-string">"cookclass"</span>),
                    foodObject.getString(<span class="hljs-string">"name"</span>),
                    foodObject.getString(<span class="hljs-string">"description"</span>),
                    foodObject.getString(<span class="hljs-string">"food"</span>),
                    foodObject.getString(<span class="hljs-string">"img"</span>),
                    foodObject.getString(<span class="hljs-string">"images"</span>),
                    foodObject.getString(<span class="hljs-string">"keywords"</span>),
                    foodObject.getString(<span class="hljs-string">"message"</span>),
                    foodObject.getString(<span class="hljs-string">"url"</span>));
            list2.add(foods2);
        }
        String s3 = list2.toString();

}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fastJsonC</span><span class="hljs-params">(List&lt;Foods&gt; foods)</span> </span>{

        String fastString = FastJsonTools.createJsonString(foods);
        String s2 = FastJsonTools.createJsonToListBean(fastString,
                Foods.class).toString();

}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">gsonC</span><span class="hljs-params">(List&lt;Foods&gt; foods)</span> </span>{

        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万条数据各个类库分别需要多少时间
  1. 50

  1. 100

  1. 500

  1. 1000

  1. 5000

  1. 1万

  1. 2万

  • 一开始测试的时候我没有取平均值,只是运行一下看看解析50条数据哪一个更快一点,竟然让我出乎意料,竟然是Android自带的jar包org.JSON!!!Gson甚至比FastJson都快这不符合情理啊……不是一直都说是阿里巴巴的FastJson最快的嘛!!!!后来我将解析50条数据提高到100、500、1000条……数据的时候就发现,随着解析数据量的增大然后逐渐的发现FastJson的优势出来了,而org.JSON却很慢了
  • 分析出现上面的结果的原因,为什么在数据量少的时候,org.json 类库拆包解析的更快呢,仔细看源码会发现:org.json在进行解析的时候需要通过for循环依次的将数据取出来放到指定对象的成员变量中 是for循环的缘故,当for循环的次数太多的时候肯定就相当耗时了,在数据量小的时候却表现的比较出色
  • 然而这样解析有着明显的问题,因为每一次测试的时间都不相同,因为不是很稳定,所以应该取一下平均值,我这就对 拆包解析的方法里加了个50次的循环
/**

  • @author 郑明亮

  • @Time:2016年8月9日 下午6:31:19

  • @version 1.0
    */<code class="java" data-origin="<pre><code class="java">@org.junit.Test
    public void TestSpeed() throws Exception {

     List&amp;lt;Foods&amp;gt; foods = foodDao.selectAll(Foods.class);
    
     System.out.println(&quot;-------------gson-----------&quot;);
     long gsonStart = System.currentTimeMillis();
     gsonC(foods);//用Gson进行拆包 和 解析 并循环操作50次
     long gsonEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (gsonEnd - gsonStart) / 50);
     System.out.println(&quot;-------------gson-----------&quot;);
    
     System.out.println(&quot;-------------FastJson-----------&quot;);
     long fastStart = System.currentTimeMillis();
     fastJsonC(foods);// 用FastJson进行拆包 和 解析 并循环操作50次
     long fastEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (fastEnd - fastStart) / 50);
     System.out.println(&quot;-------------FastJson-----------&quot;);
    
     System.out.println(&quot;-------------JSON-----------&quot;);
     long jsonStart = System.currentTimeMillis();
     jsonC(foods);// 用org.json进行拆包 和 解析 并循环操作50次
     long jsonEnd = System.currentTimeMillis();
     System.out.println(&quot;gsonGaps:&quot; + (jsonEnd - jsonStart) / 50);
     System.out.println(&quot;-------------JSON-----------&quot;);
    

    }

    private synchronized void jsonC(List&lt;Foods&gt; foods) throws Exception {
    for (int j = 0; j &lt; 50; j++) {
    String jsonString = JsonTools.createJsonString("json", foods);
    JSONObject object = new JSONObject(jsonString);
    JSONArray array = object.getJSONArray("json");
    List&lt;Foods&gt; list2 = new ArrayList&lt;Foods&gt;();
    for (int i = 0; i &lt; array.length(); i++) {

             JSONObject foodObject = (JSONObject) array.get(i);
             Foods foods2 = new Foods(foodObject.getInt(&quot;id&quot;),
                     foodObject.getString(&quot;cookclass&quot;),
                     foodObject.getString(&quot;name&quot;),
                     foodObject.getString(&quot;description&quot;),
                     foodObject.getString(&quot;food&quot;),
                     foodObject.getString(&quot;img&quot;),
                     foodObject.getString(&quot;images&quot;),
                     foodObject.getString(&quot;keywords&quot;),
                     foodObject.getString(&quot;message&quot;),
                     foodObject.getString(&quot;url&quot;));
             list2.add(foods2);
         }
         String s3 = list2.toString();
     }
    

    }

    private synchronized void fastJsonC(List&lt;Foods&gt; foods) {
    for (int i = 0; i &lt; 50; i++) {
    String fastString = FastJsonTools.createJsonString(foods);
    String s2 = FastJsonTools.createJsonToListBean(fastString,
    Foods.class).toString();
    }
    }

    private synchronized void gsonC(List&lt;Foods&gt; foods) {
    for (int i = 0; i &lt; 50; i++) {
    String gsonString = GsonTools.createJsonString(foods);
    String s1 = GsonTools.StringTolist(gsonString, Foods[].class)
    .toString();
    }
    }
    </code></pre>">@org.junit.Test
    public void TestSpeed() throws Exception
    {

     List&lt;Foods&gt; foods = foodDao.selectAll(Foods.class);
    
     System.out.println(<span class="hljs-string">"-------------gson-----------"</span>);
     <span class="hljs-keyword">long</span> gsonStart = System.currentTimeMillis();
     gsonC(foods);<span class="hljs-comment">//用Gson进行拆包 和 解析 并循环操作50次</span>
     <span class="hljs-keyword">long</span> gsonEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (gsonEnd - gsonStart) / <span class="hljs-number">50</span>);
     System.out.println(<span class="hljs-string">"-------------gson-----------"</span>);
    
     System.out.println(<span class="hljs-string">"-------------FastJson-----------"</span>);
     <span class="hljs-keyword">long</span> fastStart = System.currentTimeMillis();
     fastJsonC(foods);<span class="hljs-comment">// 用FastJson进行拆包 和 解析 并循环操作50次</span>
     <span class="hljs-keyword">long</span> fastEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (fastEnd - fastStart) / <span class="hljs-number">50</span>);
     System.out.println(<span class="hljs-string">"-------------FastJson-----------"</span>);
    
     System.out.println(<span class="hljs-string">"-------------JSON-----------"</span>);
     <span class="hljs-keyword">long</span> jsonStart = System.currentTimeMillis();
     jsonC(foods);<span class="hljs-comment">// 用org.json进行拆包 和 解析 并循环操作50次</span>
     <span class="hljs-keyword">long</span> jsonEnd = System.currentTimeMillis();
     System.out.println(<span class="hljs-string">"gsonGaps:"</span> + (jsonEnd - jsonStart) / <span class="hljs-number">50</span>);
     System.out.println(<span class="hljs-string">"-------------JSON-----------"</span>);
    

    }

    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 = <span class="hljs-keyword">new</span> Foods(foodObject.getInt(<span class="hljs-string">"id"</span>),
                     foodObject.getString(<span class="hljs-string">"cookclass"</span>),
                     foodObject.getString(<span class="hljs-string">"name"</span>),
                     foodObject.getString(<span class="hljs-string">"description"</span>),
                     foodObject.getString(<span class="hljs-string">"food"</span>),
                     foodObject.getString(<span class="hljs-string">"img"</span>),
                     foodObject.getString(<span class="hljs-string">"images"</span>),
                     foodObject.getString(<span class="hljs-string">"keywords"</span>),
                     foodObject.getString(<span class="hljs-string">"message"</span>),
                     foodObject.getString(<span class="hljs-string">"url"</span>));
             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. 1万

  1. 2万

  1. 100条

我10万+的数据大概是40多M,也就是说1万条数据的话大概是4M,就从我的测试结果来看,还真不知道他们那个解析4Mjson数据需要用大概2000毫秒的时间,我测试的2万条数据也就是大概8M的json数据,即使是用org.json来拆包、解析都要比这个时间要短很多,更何况我们还有出色的fastJson等优秀类库。

经过这次测试之后,确实验证了阿里巴巴的FastJson相对来说是挺快的,如果用json解析的话,还是建议用fastjson吧

generated by haroopad

 

如果,您认为这篇博客让您有些收获,不妨点击一下【】。

如果,您希望更容易地发现我的新博客,不妨点击一下【加关注】。

因为,我的热情需要您的肯定和支持。 

感谢您的阅读,如果文章中有错误或者您有什么好的建议,也欢迎您直接留言批评指教。Thanks,friends!