最近、JavaScriptエンジンのパフォーマンステストは非常に一般的になりましたが、主にクライアントサイドJavaScriptに関係しています。 私は質問に興味がありました:サーバーサイドで物事はどうなっているのですか? しかし、Google V8とSpiderMonkeyだけをテストするのは面白くないでしょう。 結果はクライアント側の結果と同様であることは明らかです。エンジンは同じです。 したがって、ブラウザで利用できないものをテストに追加する必要がありましたが、それは非常に一般的であり、サーバータスクに固有のテストを使用することも試みます。 この欠落したテストオブジェクトは、.Net FrameworkのJScriptコンパイラーによって確認されました。 しかし、予備テストの結果は私を驚かせたので、同じチームの4人目のプレーヤーを追加することにしました。
。
まず第一に、私はテストの100%客観性という目標を設定しなかったと言わなければなりません。 目標は、腕の長さ(グーグルで5分間)でアクセスできるエンジンと、私がアクセスできる環境でテストすることでした。 そしてこれ:
AMD Sempron 2800+ 1.6GHz 1Gb RAM上のWindows XP SP3
Intel Core i5 650 3.2GHz 4Gb RAM上のWindows 7 x64
タスクの単純さにもかかわらず、結果の取得は数日間続きました。
テスト方法
簡単なテスト方法が選択されました。 各テストは、ループで多数回実行するために起動される特定の機能です。 サイクル全体の実行時間が測定されます。 各反復の平均実行時間は、評価基準として使用されます。 統計的信頼性の原則に従っていませんでした-テストを連続して数回実行し、平均偏差を計算します。 私の意見では、このアプローチには、テストを数回実行して平均偏差を計算するよりも深い分析が必要です。
テスト自体がテストにかかる時間を評価するために、最初のテストは空の関数になります。 さらに、デッドコードを削除するためのテクノロジに関連する最近の傾向に照らして、テストではこの要素を何らかの形で考慮したかったのです。 テストされた関数が特定の結果を返すように要件を設定するよりも、特定の関数が何をするかに基づいて、それは私には決して起こりませんでした。 したがって、cな最適化手法には、「必要な」コードをスローする理由がないことを期待しています。 当然、cな最適化は、関数の結果がそれ以上使用されないことに基づいてコードを捨てることができます。 そのため、テストする各関数に追加のパラメーターを追加しました-結果を集計するための関数です。 集計結果自体もテストの結果になります。 サイクルの結果に対する集約自体の効果を評価するために、集約せずに再度実行しました。 また、デッドコードを排除するための最適化があるかどうかを主観的に評価するのにも役立ちます。
テストの実行と結果の処理の利便性のために、小さなフレームワークを作成しました。 さらに、各エンジンのテスト結果を均一に出力するために、独自のアダプターモジュールが使用されました。 結果はhtmlでフォーマットされ、コンソールに表示され、ストリームのリダイレクトを通じて単一のファイルに蓄積されました。
テスト全体を実行するために、CMDファイルの小さなセットが使用されました。
プレイヤー
最初のプレーヤーは有望で人気が高まっているGoogle V8エンジンであり、Google Chromeで実行され、それほど有望ではない
NodeJSの形式でテストで提示されます。 テスト結果は私を失望させないと確信していました。
2番目のプレーヤーは、豊かな歴史を持つかなり高速なエンジンです
。SpiderMonkeyは、FireFoxで動作し、
JSDBの代わりに
動作するテストで
動作します。 ここで、クライアント側のテストとの大きな違いも期待していませんでした。
3番目のプレーヤーは、MicrosoftのJavaScriptコンパイラーです。 インタープリターと比較して、コンパイラーの使用がどのような利益をもたらすのか疑問に思っていました。
4番目のプレーヤー-より完全な比較のために、Microsoftの別のインタープリターを使用するとよいでしょう。
インタープリターをテストする場合、すべてのテストファイル、フレームワーク、アダプターをコピーコマンドで単一のファイルにマージし、結果のファイルをインタープリターに渡しました。 NodeJSの場合はnodejs.exe、JSDBの場合はjsdb.exe、Microsoftのインタープリターの場合はcscript.exeユーティリティで表されるWindowsスクリプトホストです。
コンパイラの場合、すべてのファイルには、対応するバージョンの.Net Frameworkからjsc.exeが供給され、結果のexeファイルが起動されました。
各プラットフォームでのプレイヤーの募集は異なっていました。
Windows XP
- NodeJS v 0.2.4
- JSDB 1.8.0.3
- Microsoft JScript 5.6.8825インタープリター
- Microsoft JScript 5.7.16599
- Microsoft JScript 5.8.18702インタープリター
- Microsoft .NET v.1.1.4322.2032のJScriptコンパイラー
- Microsoft .NET v.2.0.50727.3053のJScriptコンパイラ
- Microsoft .NET v.4.0.30319.1のJScriptコンパイラ
Windows 7
- NodeJS v 0.2.4
- JSDB 1.8.0.3
- Microsoft JScript 5.8.16475インタープリター
- Microsoft JScript 9.0.16406インタープリター
- Microsoft .NET v.4.0.30319.1のJScriptコンパイラ
はい 私は間違っていませんでした。 Microsoft JScript 9.0.16406は、IE9で使用されるまさにそのエンジンです。 IE9自体をインストールせずにWindows Script Hostで動作させるために、少し工夫する必要がありました。 インストールパッケージのライブラリは異なる方法で呼び出され、その隣にIE 8の古いエンジンが通常の名前で置かれているため、インストール後にWSHで使用できるかどうかさえわかりません。
Windows 7では、.NET v.2.0からコンパイラにアクセスできましたが、何らかの理由でその下のテストがエラーで失敗しました。詳細は後で説明します。
Microsoftのさまざまなバージョンのエンジンを使用して、バージョン間で速度に進歩があるかどうか、またどのバージョンに進歩があるかを確認しました。 彼らは私の足の下に横たわりました。 なぜそれらをテストに含めないのですか?
テスト
さらに、テストごとに、テストした機能と、すべてのエンジンの平均サイクル時間の結果を示します。 最後にすべてのテスト結果。
空の関数
tests.push({
name: 'Empty test' ,
func: function (){ return 1;},
reduce: function (r,x){ return r+x;},
start: 0,
loops: 1000000
});
* This source code was highlighted with Source Code Highlighter .
ここで、funcはテスト中の関数、reduceはアグリゲーター関数、startはアグリゲーターの開始値、loopsはテストのサイクル数です。
Windows XPでの空のテスト結果(少ないほど良い)

Windows 7での空のテスト結果(少ないほど良い)

文字列の連結
典型的なストリング操作のテスト。
var str1 = 'Hello ' ,
str2 = 'world ' ,
str3 = 'test ' ,
i = 0;
tests.push({
name: 'String Concat' ,
func: function (){
i++;
return str1+str2+str3+ ' ' +i;
},
reduce: function (r,x){ return r+x.length;},
start: 0,
loops: 100000
});
* This source code was highlighted with Source Code Highlighter .
Windows XPでの文字列連結の結果(少ないほど良い)

Windows 7での文字列連結の結果(少ない方が良い)

テンプレートにデータを入力する
私の意見では、典型的なサーバー操作。
var template = '<html><title>{title}</title><body>{main}</body></html>' ;
function ApplyTemplate(template, view){
return template.replace(/{(\w+)}/g, function (p,n){
if (n in view) return view[n];
else return '_ERROR_NO_VALUE_' +n;
});
}
var views = [
{
title: 'Page One' ,
main: 'Lorem ipsum dolor sit amet, mauris libero velit, ' +
'vitae pellentesque aliquam, cursus magnis velit, non ' +
'viverra sed nibh ac fringilla vel, accumsan quis ' +
'elementum fermentum ullamcorper. ' +
/* .... */
'lectus libero at etiam morbi, et orci eros ut sit et.'
},
{
title: 'Page two' ,
main: 'Short page'
}
];
var counter = 0;
tests.push({
name: 'Apply template' ,
func: function (){
counter++;
return ApplyTemplate(template, views[counter%2]);
},
reduce: function (r,x){ return r+x.length;},
start: 0,
loops: 10000
});
* This source code was highlighted with Source Code Highlighter .
テンプレートの結果をWindows XPに適用する(少ないほど良い)

Windows 7でテンプレートの結果を適用する(少ないほど良い)
Google V8 Benchmark Suiteバージョン6から次のテストを受け
ました 。
残念ながら、これらのテストにはエラーがたくさんあることが判明しました。 エラーは、JScriptコンパイラによって私に指摘されました。 一部のエラーは、JScriptとJavaScriptの不完全な互換性に関連していました。 一部は本当に間違いでした。 問題が最も少ない3つのテストを行いました。 フレームワークに少し適合させ、エラーを修正しました。 Sunspiderからテストを受けることもできましたが、残念ながら、便利なjsソースの形でそれらを見つけることができませんでした。 テストでサイトに表示されるバージョンは、htmlに組み込まれているため、パーサーによる処理が必要です。
ここでは、これらのテストのソースではなく、結果のみを提供します。
V8ベンチマークスイートリチャーズ
サイトで述べたように、OSカーネルの動作をシミュレートします。
V8 BSの結果-Windows XP上のリチャーズ(少ない方が良い)

V8 BSの結果-Windows 7上のリチャーズ(少ない方が良い)

V8 Benchmark Suite Encrypt
データのエンコード。
V8 BSの結果-Windows XPでの暗号化(少ない方が良い)

V8 BSの結果-Windows 7での暗号化(少ない方が良い)

V8 Benchmark Suite Decrypt
データのデコード。
V8 BSの結果-Windows XPでの復号化(少ないほど良い)

V8 BSの結果-Windows 7での復号化(少ないほど良い)

V8ベンチマークスイートRegExp
インターネット上の50の人気サイトから抽出された正規表現。
V8 BSの結果-Windows XPでのRegExp(少ない方が良い)

V8 BSの結果-Windows 7でのRegExp(少ない方が良い)

Windows XPでの結果の完全な表。
NodeJS v 0.2.4
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 21 | 0.000021 | 44 | 0.000044 | 1,000,000 |
ストリング連結 | 100,000 | 44 | 0.00044 | 47 | 0.00047 | 2288895 |
テンプレートを適用 | 10,000 | 32 | 0.0032 | 28 | 0.0028 | 590000 |
V8 BS-リチャーズ | 1000 | 4879 | 4.879 | 4702 | 4.702 | 0 |
V8 BS-暗号化 | 100 | 345 | 3.45 | 356 | 3.56 | 0 |
V8 BS-復号化 | 100 | 7496 | 74.96 | 7514 | 75.14 | 0 |
V8 BS-正規表現 | 100 | 11620 | 116.2 | 11913 | 119.13 | 0 |
Microsoft .NET v.1.1.4322.2032
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 1891 | 0.001891 | 4094 | 0.004094 | 1,000,000 |
ストリング連結 | 100,000 | 344 | 0.00344 | 859 | 0.00859 | 2288895 |
テンプレートを適用 | 10,000 | 532 | 0.0532 | 609 | 0.0609 | 590000 |
V8 BS-リチャーズ | 25 | 9266 | 370.64 | 9390 | 375.6 | 0 |
V8 BS-暗号化 | 10 | 2875 | 287.5 | 3062 | 306.2 | 0 |
V8 BS-復号化 | 5 | 33657 | 6731.4 | 32078 | 6415.6 | 0 |
V8 BS-正規表現 | 10 | 32296 | 3229.6 | 33219 | 3321.9 | 0 |
Microsoft .NET v.2.0.50727.3053
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 3328 | 0.003328 | 8578 | 0.008578 | 1,000,000 |
ストリング連結 | 100,000 | 515 | 0.00515 | 1297 | 0.01297 | 2288895 |
テンプレートを適用 | 10,000 | 547 | 0.0547 | 657 | 0.0657 | 590000 |
V8 BS-リチャーズ | 25 | 9703 | 388.12 | 9859 | 394.36 | 0 |
V8 BS-暗号化 | 10 | 2531 | 253.1 | 2875 | 287.5 | 0 |
V8 BS-復号化 | 5 | 25344 | 5068.8 | 25047 | 5009.4 | 0 |
V8 BS-正規表現 | 10 | 29032 | 2903.2 | 29234 | 2923.4 | 0 |
Microsoft .NET v.4.0.30319.1
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 2188 | 0.002188 | 5282 | 0.005282 | 1,000,000 |
ストリング連結 | 100,000 | 437 | 0.00437 | 1125 | 0.01125 | 2288895 |
テンプレートを適用 | 10,000 | 500 | 0.05 | 610 | 0.061 | 590000 |
V8 BS-リチャーズ | 25 | 9812 | 392.48 | 10031 | 401.24 | 0 |
V8 BS-暗号化 | 10 | 2719 | 271.9 | 3469 | 346.9 | 0 |
V8 BS-復号化 | 5 | 28140 | 5628 | 28297 | 5659.4 | 0 |
V8 BS-正規表現 | 10 | 34437 | 3443.7 | 33016 | 3301.6 | 0 |
JSDB 1.8.0.3
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 343 | 0.000343 | 719 | 0.000719 | 1,000,000 |
ストリング連結 | 100,000 | 703 | 0.00703 | 547 | 0.00547 | 2288895 |
テンプレートを適用 | 10,000 | 383 | 0.0383 | 233 | 0.0233 | 590000 |
V8 BS-リチャーズ | 1000 | 48319 | 48.319 | 49948 | 49.948 | 0 |
V8 BS-暗号化 | 10 | 905 | 90.5 | 925 | 92.5 | 0 |
V8 BS-復号化 | 10 | 16571 | 1657.1 | 16475 | 1647.5 | 0 |
V8 BS-正規表現 | 10 | 15968 | 1596.8 | 13636 | 1363.6 | 0 |
Microsoft JScript 5.6.8825
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 2578 | 0.002578 | 5812 | 0.005812 | 1,000,000 |
ストリング連結 | 100,000 | 4531 | 0.04531 | 4844 | 0.04844 | 2288895 |
テンプレートを適用 | 10,000 | 1344 | 0.1344 | 1375 | 0.1375 | 410000 |
V8 BS-リチャーズ | 100 | 18484 | 184.84 | 18422 | 184.22 | 0 |
V8 BS-暗号化 | 10 | 1813 | 181.3 | 1797 | 179.7 | 0 |
V8 BS-復号化 | 10 | 32500 | 3250 | 32187 | 3218.7 | 0 |
V8 BS-正規表現 | 10 | 37938 | 3793.8 | 37547 | 3754.7 | 0 |
Microsoft JScript 5.7.16599
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 4235 | 0.004235 | 6562 | 0.006562 | 1,000,000 |
ストリング連結 | 100,000 | 1625 | 0.01625 | 1969 | 0.01969 | 2288895 |
テンプレートを適用 | 10,000 | 562 | 0.0562 | 594 | 0.0594 | 410000 |
V8 BS-リチャーズ | 100 | 22328 | 223.28 | 22625 | 226.25 | 0 |
V8 BS-暗号化 | 10 | 1797 | 179.7 | 1813 | 181.3 | 0 |
V8 BS-復号化 | 10 | 33953 | 3395.3 | 32219 | 3221.9 | 0 |
V8 BS-正規表現 | 10 | 27813 | 2781.3 | 29609 | 2960.9 | 0 |
Microsoft JScript 5.8.18702
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 1171 | 0.001171 | 1532 | 0.001532 | 1,000,000 |
ストリング連結 | 100,000 | 844 | 0.00844 | 1235 | 0.01235 | 2288895 |
テンプレートを適用 | 10,000 | 359 | 0.0359 | 359 | 0.0359 | 410000 |
V8 BS-リチャーズ | 100 | 11906 | 119.06 | 12094 | 120.94 | 0 |
V8 BS-暗号化 | 10 | 1610 | 161 | 1578 | 157.8 | 0 |
V8 BS-復号化 | 10 | 26875 | 2687.5 | 27281 | 2728.1 | 0 |
V8 BS-正規表現 | 10 | 22781 | 2278.1 | 22391 | 2239.1 | 0 |
Windows 7での結果の完全な表。
NodeJS v 0.2.4
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 12 | 0.000012 | 14 | 0.000014 | 1,000,000 |
ストリング連結 | 100,000 | 17 | 0.00017 | 13 | 0.00013 | 2288895 |
テンプレートを適用 | 10,000 | 9 | 0.0009 | 11 | 0.0011 | 590000 |
V8 BS-リチャーズ | 1000 | 1640 | 1.64 | 1749 | 1.749 | 0 |
V8 BS-暗号化 | 100 | 120 | 1.2 | 128 | 1.28 | 0 |
V8 BS-復号化 | 100 | 2570 | 25.7 | 2573 | 25.73 | 0 |
V8 BS-正規表現 | 100 | 3996 | 39.96 | 3996 | 39.96 | 0 |
JSDB 1.8.0.3
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 89 | 0.000089 | 221 | 0.000221 | 1,000,000 |
ストリング連結 | 100,000 | 177 | 0.00177 | 167 | 0.00167 | 2288895 |
テンプレートを適用 | 10,000 | 33 | 0.0033 | 33 | 0.0033 | 590000 |
V8 BS-リチャーズ | 1000 | 17738 | 17.738 | 17780 | 17.78 | 0 |
V8 BS-暗号化 | 10 | 272 | 27.2 | 276 | 27.6 | 0 |
V8 BS-復号化 | 10 | 5095 | 509.5 | 5103 | 510.3 | 0 |
V8 BS-正規表現 | 10 | 3454 | 345.4 | 3499 | 349.9 | 0 |
Microsoft .NET v.4.0.30319.1
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 574 | 0.000574 | 1344 | 0.001344 | 1,000,000 |
ストリング連結 | 100,000 | 149 | 0.00149 | 334 | 0.00334 | 2288895 |
テンプレートを適用 | 10,000 | 140 | 0.014 | 281 | 0.0281 | 590000 |
V8 BS-リチャーズ | 25 | 2268 | 90.72 | 2576 | 103.04 | 0 |
V8 BS-暗号化 | 10 | 471 | 47.1 | 2813 | 281.3 | 0 |
V8 BS-復号化 | 5 | 4908 | 981.6 | 5018 | 1003.6 | 0 |
V8 BS-正規表現 | 10 | 8762 | 876.2 | 8805 | 880.5 | 0 |
Microsoft .NET v.4.0.30319.1
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 516 | 0.000516 | 1293 | 0.001293 | 1,000,000 |
ストリング連結 | 100,000 | 118 | 0.00118 | 273 | 0.00273 | 2288895 |
テンプレートを適用 | 10,000 | 136 | 0.0136 | 301 | 0.0301 | 590000 |
V8 BS-リチャーズ | 25 | 2188 | 87.52 | 2477 | 99.08 | 0 |
V8 BS-暗号化 | 10 | 470 | 47 | 3000 | 300 | 0 |
V8 BS-復号化 | 5 | 4831 | 966.2 | 5049 | 1009.8 | 0 |
V8 BS-正規表現 | 10 | 8704 | 870.4 | 8826 | 882.6 | 0 |
Microsoft JScript 5.8.16475
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 244 | 0.000244 | 502 | 0.000502 | 1,000,000 |
ストリング連結 | 100,000 | 168 | 0.00168 | 224 | 0.00224 | 2288895 |
テンプレートを適用 | 10,000 | 90 | 0.009 | 95 | 0.0095 | 410000 |
V8 BS-リチャーズ | 100 | 4391 | 43.91 | 4400 | 44 | 0 |
V8 BS-暗号化 | 10 | 611 | 61.1 | 619 | 61.9 | 0 |
V8 BS-復号化 | 10 | 10502 | 1050.2 | 10512 | 1051.2 | 0 |
V8 BS-正規表現 | 10 | 4768 | 476.8 | 4772 | 477.2 | 0 |
Microsoft JScript 9.0.16406
お名前 | ループ | 時間 | 平均 | 時間 | 平均wr | 解像度 |
---|
空のテスト | 1,000,000 | 41 | 0.000041 | 82 | 0.000082 | 1,000,000 |
ストリング連結 | 100,000 | 38 | 0.00038 | 39 | 0.00039 | 2288895 |
テンプレートを適用 | 10,000 | 18 | 0.0018 | 17 | 0.0017 | 590000 |
V8 BS-リチャーズ | 100 | 166 | 1.66 | 166 | 1.66 | 0 |
V8 BS-暗号化 | 10 | 15 | 1.5 | 37 | 3.7 | 0 |
V8 BS-復号化 | 10 | 253 | 25.3 | 246 | 24.6 | 0 |
V8 BS-正規表現 | 10 | 3175 | 317.5 | 3188 | 318.8 | 0 |
結論
.NETコンパイラー(より正確には、その作業の結果)が最も遅いことが判明しました。 私が何か間違ったことをしているのか、彼はただダメです。 9バージョン未満のMicrosoftバージョンの通訳者は、テンプレートの使用に関するテストに失敗しました。結果は他とは異なります。 綿密な調査により、置換のためのコールバック関数へのパラメーターの割り当てが異なることが示されました。
Windows 7では、.NET Framework 2.0からコンパイラーのバージョンをテストすることはできませんでした。バージョン4.0の動作も同様です。 テストは20分間機能しました。 バージョン2.0はエラーでクラッシュしました。 両方のバージョンで、テストは最大6 GBのメモリを消費しました。 なぜテスト自体がそのような破滅的な時間を示さなかったのですか? 問題を詳しく調べたところ、Windows 7 x64向けコンパイラの奇妙な機能が明らかになりました。V8BS-Regexpテストが問題を引き起こしました。 さらに、コンパイルされたプログラムは、コードの実行が始まる前からメモリを使い果たしていました。 .Netは、コードが実行される前であっても、このテストで豊富にある正規表現を何らかの方法で初期化するようです。 さらに、クロージャーを作成する関数に正規表現が含まれている場合、問題が発生します。
私の最終的な結論は次のとおりです。.NETFrameworkのJScriptコンパイラは、コンパイルエラーのコードをテストする以外に何の役にも立ちません。 また、このようなタスクでC#がどのように異なるかをテストすることも興味深いものになりました。 ただし、エラーメッセージを表示するときにスタックトレースを見ると、JScript .NETの「高速」障害がより明確になり始めます。 単純な呼び出しのラッパーはあまり見ていません。
ただし、Microsoft JScript 9.0の新しいインタープリターは非常に競争力があり、ActiveScriptingを介してそのクラスを簡単に拡張できます。 興味深いのはバージョンの選択です。 IE8で使用されていたバージョン5.8の後、バージョン9.0が突然登場したのはなぜですか? ただし、公式リリース後、すべてが変更される場合があります。
NodeJSでのGoogle V8の短さのリーダーですが、JScript 9.0はすぐに登場します。 最終的な選択は、速度の基準だけでなく、要因の合計によっても安全に行えるように思えます。 拡張、デバッグ、プラットフォームとの統合の利便性を含みます。
そして最後に-意味のない、純粋に例示的な図。 NodeJSの時間と各テストの時間の比率をとり、テスト全体で平均しました。
評価エンジン(詳細-より良い)

参照:
NodeJSJsdbGoogle V8 Benchmark Suiteバージョン6Microsoft WindowsスクリプトホストMicrosoft jscript