JSON.stringify以及JSON.parse的效率

 Fri, 12 Nov 2010 20:00:41 +0800

之前參加IT邦鐵人賽,在一個沒做出來的例子中,發現某些瀏覽器對從Canvas 2D Context用getImageData取得的CanvasPixelArray做JSON.stringify/JSON.parse速度奇慢,當時只是粗略的測試。為了仔細觀察到底不同瀏覽器的JSON處理效率,我索性做兩個資料來做比對,一個是640x480的CanvasPixelArray,一個是相同結構的Object。

CanvasPixelArray有兩個重要的使用方式,其中,使用length性可以取得他的「陣列」(他不是一個真正的陣列)長度,用數字當作索引,可以取得依照RGBA順序排列的值。所以一個640x480的Canvas,取得的CanvasPixelArray元素個數應該有640x480x4。跟CanvasPixelArray做對照的是一個JSON.stringify後,結果相同的Object。然後測試兩個樣本執行JSON.stringify以及JSON.parse的執行速度。程式如下:

<html>
<head>
<style>
  div {
    border: solid 1px #336699;
    background: #AADDFF;
    width: 800px;
    padding: 10px;
    margin: 5px;
    border-radius: 5px;
    -moz-border-radius: 5px;
    text-align: justify;
  }
</style>
</head>
<body>
<canvas id="canvas" width="640" height="480"></canvas>
<div id="panel"></div>
</body>
</html>
<script>
document.getElementById('panel').innerHTML += 'Preparing CanvasPixelArray for testing...<br>';
var ctx = document.getElementById('canvas').getContext('2d');
var img = ctx.getImageData(0,0,640,480);
document.getElementById('panel').innerHTML += 'Preparing Object for testing...<br>';
var obj = {};
for(var i=0,j=640*480*4; i<j; i++) {
  obj[''+i+''] = 0;
}
obj['length'] = 640*480;
function test1() {
  var time1 = new Date().getTime();
  txt = JSON.stringify(img.data);
  var time1a = new Date().getTime();
  document.getElementById('panel').innerHTML += 'JSON.stringify CanvasPixelArray: ' + (time1a-time1)/1000 + 'secs <br>';
  setTimeout(test2, 100);
}
function test2() {
  var time2 = new Date().getTime();
  var tmp = JSON.parse(txt);
  var time2a = new Date().getTime();
  document.getElementById('panel').innerHTML += 'JSON.parse CanvasPixelArray: ' + (time2a-time2)/1000 + 'secs <br>';
}
setTimeout(test1, 100);
function test3() {
  var time1 = new Date().getTime();
  txt1 = JSON.stringify(obj);
  var time1a = new Date().getTime();
  document.getElementById('panel').innerHTML += 'JSON.stringify Object: ' + (time1a-time1)/1000 + 'secs <br>';
  setTimeout(test4, 100);
}
function test4() {
  var time2 = new Date().getTime();
  var tmp = JSON.parse(txt1);
  var time2a = new Date().getTime();
  document.getElementById('panel').innerHTML += 'JSON.parse Object: ' + (time2a-time2)/1000 + 'secs <br>';
}
setTimeout(test3, 3000);
</script>

測試的結果還是讓我蠻訝異的:

雖然只是很粗略的測試,而且只跑一次(所以不夠格當作樣本),但是一些速度的差距太明顯,所以很有意思。Google Chrome雖然速度很快,但是他的JSON處理速度有點慘不忍睹(Safari也一樣,但是Safari會警告Javascript執行逾時,測試根本跑不完)。Opera的JSON.parse速度讓人驚艷。Firefox4 Beta7的速度反而不及Firefox 3.6.12。而Firefox 3.6.12處理CanvasPixelArray的速度很明顯地比Object快,這也跟預期不太一樣。