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快,這也跟預期不太一樣。