JavaScript解析Json字符串的性能比较

我们在使用AJAX来做服务器端和客户端交互的时候,一般的做法是让服务器端返回一段JSON字符串,然后在客户端把它解析成JavaScript对象。解析时用到的方法一般是eval或者new function,而目前IE8和Firefox3.1又内置了原生的JSON对象(据说会有一定的性能提升)。那我们在实际使用的时候怎样从这三种方法(因为性能问题,不考虑用javascript实现的解析)里面来选择呢?面对众多的浏览器,哪种方式的性能是最好的呢?

一、测试方法

1、首先指定测试次数及JSON字符串

   1: var count = 10000, o = null, i = 0, jsonString = '{"value":{"items": [{"x":1,"y":2,"z":3}, {"x":1,"y":2,"z":3}, {"x":1,"y":2,"z":3}, {"x":1,"y":2,"z":3}, {"x":1,"y":2,"z":3}]},"error":null}';

2、循环解析并记录时间

  • eval
   1: var beginTime = new Date();
   2: for ( i = 0; i < count; i++ ) {
   3:     o = eval( "(" + jsonString + ")" );
   4: }
   5: Console.output( "eval:" + ( new Date() - beginTime ) );
  • new Function
   1: var beginTime = new Date();
   2: for ( i = 0; i < count; i++ ) {
   3:     o = new Function( "return " + jsonString )();
   4: }
   5: Console.output( "new Function:" + ( new Date() - beginTime ) );
  • native
   1: if ( typeof JSON !== "undefined" ) {
   2:     var beginTime = new Date();
   3:     for ( i = 0; i < count; i++ ) {
   4:         o = JSON.parse( jsonString );     }
   5:     Console.output( "native:" + ( new Date() - beginTime ) );
   6: } else {
   7:     Console.output( "native:not support!" );
   8: }

二、测试对象

选择目前主流的浏览器(不考虑Maxthon一类的外壳),包括IE6、7、8,Firefox2、3、3.1,Chrome,Opera及Safari3、4。

 

三、测试环境

T9300 CPU + 4G RAM + Windows2003,其中IE8使用的是Vista的环境,IE7在另外一台工作机(2G CPU + 2G RAM + Windows2003),考虑到主要是测试浏览器客户端的性能,结果的误差应该能够接受。

 

四、测试结果

*数值越小越好

*在当前列中绿色背景的表示性能最好,红色性能最差

1、Firefox2、3全部垫底,IE6的性能优于IE7(可能和机器不一致有关),Chrome和Safari4的性能远远超出其它浏览器。

2、不同的浏览器下eval和new Function的性能不一致,总的来说eval更好,但Firefox下new Function的性能是eval的一倍,为了更好的兼容各个浏览器,我们把对JSON的解析单独封装成一个对象来处理:

  • wrapper
   1: var __json = null;
   2: if ( typeof JSON !== "undefined" ) {
   3:     __json = JSON;
   4: }
   5: var browser = Browser;
   6: var JSON = {
   7:     parse: function( text ) {
   8:         if ( __json !== null ) {
   9:             return __json.parse( text );
  10:         }
  11:         if ( browser.gecko ) {
  12:             return new Function( "return " + text )();
  13:         }
  14:         return eval( "(" + text + ")" )
  15:     }
  16: };          
  17: var beginTime = new Date();
  18: for ( i = 0; i < count; i++ ) {
  19:     o = JSON.parse( jsonString ); }
  20: Console.output( "wrapper:" + ( new Date() - beginTime ) );

加入Wrapper后的结果:

由于涉及到调用对象的开销,封装后JSON对象会比单独调用更慢,但它能保证在各个浏览器下使用最适合的方法。

 

五、结论

解析Json字符串时,不同的浏览器选择不同的方法:

  • IE6、7使用eval
  • IE8使用原生的JSON对象
  • Firefox2、3使用new Function
  • Safari4使用eval
  • 其它浏览器下eval和new Function的性能基本一致

如果有不同意见欢迎拍砖:)

附:全部代码

图片[1]-JavaScript解析Json字符串的性能比较-千百度社区
图片[2]-JavaScript解析Json字符串的性能比较-千百度社区
Code

DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd&#8221;>
<html>
    
<head>
        
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
        
<title>Parse JsonString title>
    
head>
    
<body>
        
<div id=”consoleRegion”> div>
        
<script type=”text/javascript”>
            
//yui
            var Browser = function() {
                
var o = {
                    ie: 
0,
                    opera: 
0,
                    gecko: 
0,
                    webkit: 
0
                };
                
var ua = navigator.userAgent, m;
                
if ( ( /KHTML/ ).test( ua ) ) {
                    o.webkit 
= 1;
                }
                
// Modern WebKit browsers are at least X-Grade
                m = ua.match(/AppleWebKit\/([^\s]*)/);
                if (m&&m[1]) {
                    o.webkit
=parseFloat(m[1]);
                }

                if (!o.webkit) { // not webkit
                    // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
                    m=ua.match(/Opera[\s\/]([^\s]*)/);
                    if (m&&m[1]) {
                        o.opera
=parseFloat(m[1]);
                    } 
else { // not opera or webkit
                        m=ua.match(/MSIE\s([^;]*)/);
                        
if (m&&m[1]) {
                            o.ie
=parseFloat(m[1]);
                        } 
else { // not opera, webkit, or ie
                            m=ua.match(/Gecko\/([^\s]*)/);
                            if (m) {
                                o.gecko
=1// Gecko detected, look for revision
                                m=ua.match(/rv:([^\s\)]*)/);
                                
if (m&&m[1]) {
                                    o.gecko
=parseFloat(m[1]);
                                }
                            }
                        }
                    }
                }
                
return o;
            }();

            var Console = {
                consoleRegion: 
null,

                getRegion: function() {
                    
if ( this.consoleRegion === null ) {
                        
this.consoleRegion = document.getElementById( consoleRegion );
                    }
                    
return this.consoleRegion;
                },

                output: function( text ) {

                    this.getRegion().innerHTML += 
 + text;

                }
            };
            //test code
            var count = 10000, o = null, i = 0, jsonString = {“value”:{“items”: [{“x”:1,”y”:2,”z”:3}, {“x”:1,”y”:2,”z”:3}, {“x”:1,”y”:2,”z”:3}, {“x”:1,”y”:2,”z”:3}, {“x”:1,”y”:2,”z”:3}]},”error”:null};
            
//eval
            var beginTime = new Date();
            
for ( i = 0; i < count; i++ ) {
                o 
= eval( ( + jsonString + ) );
            }
            Console.output( 
eval: + ( new Date()  beginTime ) );
            
//new Function
            beginTime = new Date();
            
for ( i = 0; i < count; i++ ) {
                o 
= new Function( return  + jsonString )();
            }
            Console.output( 
new Function: + ( new Date()  beginTime ) );
            
//native
            if ( typeof JSON !== undefined ) {
                beginTime 
= new Date();
                
for ( i = 0; i < count; i++ ) {
                    o 
= JSON.parse( jsonString );

                }
                Console.output( native: + ( new Date()  beginTime ) );
            } 
else {
                Console.output( 
native:not support! );
            }
            
//wrapper
            var __json = null;
            
if ( typeof JSON !== undefined ) {
                __json 
= JSON;
            }
            
var browser = Browser;
            
var JSON = {
                parse: 
function( text ) {
                    
if ( __json !== null ) {
                        
return __json.parse( text );
                    }
                    
if ( browser.gecko ) {
                        
return new Function( return  + text )();
                    }
                    
return eval( ( + text + ) )
                }
            };          
            beginTime 
= new Date();
            
for ( i = 0; i < count; i++ ) {
                o 
= JSON.parse( jsonString );

            }
            Console.output( wrapper: + ( new Date()  beginTime ) );
            
//alert( o.value.items[0].z );
         script>
    
body>
html>

千百度
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容