夕暮ログ

C#やJavascript、最近はAndroidなんかも好きなtinqのブログ。「夕暮れログ」

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JSON.parseとevalなどの比較とスピードテスト

JSONはjavascriptのオブジェクトの記法をベースにしたもので、主にjavascriptでオブジェクトを文字列で表す際に利用されます。 特にAjax分野ではかなり多用されます。
非常に扱いやすいので、さまざまなプログラミング言語で使うことが出来るようになってきています。

JSONは文字列なので、それをオブジェクトに変換して使うわけですが現在javascriptでやるにはいくつかの方法があります。

  • eval
  • new Function
  • JSON.parse
  • jQuery
  • json2.js

それぞれの違いについて改めて調べてみました。

eval、new Function

evalとnew Functionは古くから使われている方法です。
どちらも文字列をjavascriptとして認識、実行する方法です。
JSONはjavascriptのオブジェクトを書く方法がベースとなっているので普通に実行するだけでオブジェクトを取り出すことができます。

一番簡単でいいように思いますがこの方法には大きな問題点が存在します。
jsonの文字列の中に含まれる危険なjavascriptもそのまま実行されてしまいます
ヘタをすればXSSなどがおきて大変な脆弱性に繋がってしまうわけです。

JSON.parse

上記の問題を解決するために最近になって各ブラウザが採用したのが、JSON.parseという関数です。
これは、あいまいな形や含まれるjavascriptが実行されないように配慮がされた、JSONをオブジェクトに変換する専用の関数です。
これを使うことで安全に変換ができます。

しかし、これが追加されたのは最近のため古いブラウザ(IE6など)は対応していません。

json2.js、jQuery

古いブラウザにも対応させるならJSON.parseは使えません。かといってevalなどを使うのは危険を伴います。
そこで利用されるのがjavascriptのライブラリです。
javascriptのライブラリを使うことで、JSONの正しい形で、javascriptが実行される危険がないかなどをチェックしてからevalやnew Functionを使って処理を行います。
なので万一危険な物を変換しようとしても安全は保たれるわけです。 もちろん、チェックをするのでevalやnew Functionをそのまま使うのに比べれば速度が若干落ちますが、サイトを危険にさらすのに比べればたいしたことではありません

安全に変換するライブラリは有名なところで、json2.jsとjQueryがあります。
json2.jsはhttp://www.json.org/の下にいろいろ書いてある中のjavascriptのところ、「json2.js」からダウンロードできます。
json.jsとjson2.jsがありますが、特に理由がない場合はjson2.jsでいいようです。(違いはjson.jsの一番下にちょこっとコードが書いてあります。)
ブラウザにJSON.parseがない場合のみJSON.parseを追加しています。(もともとある場合はブラウザのほうが使われます)

jQueryの場合は普通のjQueryを読み込めば含まれています。プラグインなどは不要です。
jQuery.parseJSONという関数から使えます。内部では「Logic borrowed from http://json.org/json2.js」と書いてあるので、基本的に対してやっていることに違いはないでしょう。こちらもブラウザがもともとJSON.parseに対応していればそれを内部で利用します。

jQueryを使っているサイトならjQuery.parseJSONを、使っていないサイトではjson2.jsを使えばいいと思われます。



JSON.parseとevalとnew Functionのスピードテスト

JSON.parseとevalとnew Functionの速度を比較してみました。
 var length = 1000000; 
 function jsonParse()
 {
	var start = new Date();
	for(var i = 0 ; i < length ; i++)
	{
		JSON.parse(json);
	}
	document.getElementById("output").value = (new Date()) - start;
 }
 function jsonEval()
 {
	var start = new Date();
	for(var i = 0 ; i < length ; i++)
	{
		eval("(" + json + ")");
	}
	document.getElementById("output").value = (new Date()) - start;
 }
 function jsonFunc()
 {
	var start = new Date();
	for(var i = 0 ; i < length ; i++)
	{
		(new Function("return " + json))();
	}
	document.getElementById("output").value = (new Date()) - start;
 }
この関数をそれぞれ呼び出します。
変数jsonは短いものと少し長いものの2種類を入れてみました。
(IE8の場合はJSON.parseはCompatibility modeでは使えませんので注意してください。)

これを5回やって平均を出しました。結果は以下のようになりました。単位はms、小数点以下切捨てです。
{"hoge":"piyo"}
Firefox(7.01) GoogleChrome(14) Opera(11.50) IE8
JSON.parse 1480 1081 1310 6193
eval 2416 2486 6455 13822
new Function 15秒~20秒※1 3745 -※2 1578
{"first":"山田","name":"太郎","tel":"0000-000-0000","age":"20","from":"japan"}
Firefox(7.01) GoogleChrome(14) Opera(11.50) IE8
JSON.parse 4212 5369 4299 12853
eval 5780 4841 10708 15660
new Function 25秒程度※1 5981 - ※2 22512
※1 : 途中で遅くなっている原因のスクリプトをとめるかの確認などがでてきたり、一瞬フリーズしたりしたので参考記録
※2 : メモリを使い果たしてフリーズ

XPの化石マシンなので記録は参考までにお願いします。
また、普通ではやらないような処理をしているのでこれでどのブラウザが優れているということはいえません。(でもChromeはさすがな結果ですね)
new Functionは関数オブジェクトを作ることになるので、何度も繰り返すとどうしても速度やメモリ面では優れないようです。

結果は予想道理。やはりネイティブ実装のJSON.parseを使うのが一番高速でした
とあるサイトをみたときにJSONをまだevalでパースしているところがあったのですが、そのようなサイトもぜひ早めにJSON.parseを使うようにしてほしいところです。

関連記事

コメント

ここをクリックしてコメントを投稿

非公開コメント

トラックバック

http://tinqwill.blog59.fc2.com/tb.php/72-cb125867

-

管理人の承認後に表示されます

« next  ホーム  prev »

プロフィール

tinq tinq(もしくはTinqWill)

Sky  For   Every 改装予定

プログラミングお勉強中の高校生。月一くらいは更新したい

最新記事

カテゴリ

月別アーカイブ

検索フォーム

最新コメント

リンク

最新トラックバック

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。