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 8(8.0.552.200 beta)
- CanvasPixelArray
- JSON.stringify:5.184 seconds
- JSON.parse:12.273 seconds
- Object
- JSON.stringify:4.639 seconds
- JSON.parse:9.787 seconds
- CanvasPixelArray
- Firefox 4 Beta7
- CanvasPixelArray
- JSON.stringify:2.901 seconds
- JSON.parse:3.522 seconds
- Object
- JSON.stringify:3.628 seconds
- JSON.parse:3.484 seconds
- CanvasPixelArray
- Firefox 3.6.12
- CanvasPixelArray
- JSON.stringify:0.694 seconds
- JSON.parse:1.134 seconds
- Object
- JSON.stringify:3.683 seconds
- JSON.parse:3.552 seconds
- CanvasPixelArray
- Opera 10.63
- CanvasPixelArray
- JSON.stringify:4.029 seconds
- JSON.parse:0.639 seconds
- Object
- JSON.stringify:3.984 seconds
- JSON.parse:0.638 seconds
- CanvasPixelArray
雖然只是很粗略的測試,而且只跑一次(所以不夠格當作樣本),但是一些速度的差距太明顯,所以很有意思。Google Chrome雖然速度很快,但是他的JSON處理速度有點慘不忍睹(Safari也一樣,但是Safari會警告Javascript執行逾時,測試根本跑不完)。Opera的JSON.parse速度讓人驚艷。Firefox4 Beta7的速度反而不及Firefox 3.6.12。而Firefox 3.6.12處理CanvasPixelArray的速度很明顯地比Object快,這也跟預期不太一樣。