サーバーサイド速度テスト

最近、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


  1. NodeJS v 0.2.4
  2. JSDB 1.8.0.3
  3. Microsoft JScript 5.6.8825インタープリター
  4. Microsoft JScript 5.7.16599
  5. Microsoft JScript 5.8.18702インタープリター
  6. Microsoft .NET v.1.1.4322.2032のJScriptコンパイラー
  7. Microsoft .NET v.2.0.50727.3053のJScriptコンパイラ
  8. Microsoft .NET v.4.0.30319.1のJScriptコンパイラ


Windows 7


  1. NodeJS v 0.2.4
  2. JSDB 1.8.0.3
  3. Microsoft JScript 5.8.16475インタープリター
  4. Microsoft JScript 9.0.16406インタープリター
  5. 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,000210.000021440.0000441,000,000
ストリング連結100,000440.00044470.000472288895
テンプレートを適用10,000320.0032280.0028590000
V8 BS-リチャーズ100048794.87947024.7020
V8 BS-暗号化1003453.453563.560
V8 BS-復号化100749674.96751475.140
V8 BS-正規表現10011620116.211913119.130

Microsoft .NET v.1.1.4322.2032
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00018910.00189140940.0040941,000,000
ストリング連結100,0003440.003448590.008592288895
テンプレートを適用10,0005320.05326090.0609590000
V8 BS-リチャーズ259266370.649390375.60
V8 BS-暗号化102875287.53062306.20
V8 BS-復号化5336576731.4320786415.60
V8 BS-正規表現10322963229.6332193321.90

Microsoft .NET v.2.0.50727.3053
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00033280.00332885780.0085781,000,000
ストリング連結100,0005150.0051512970.012972288895
テンプレートを適用10,0005470.05476570.0657590000
V8 BS-リチャーズ259703388.129859394.360
V8 BS-暗号化102531253.12875287.50
V8 BS-復号化5253445068.8250475009.40
V8 BS-正規表現10290322903.2292342923.40

Microsoft .NET v.4.0.30319.1
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00021880.00218852820.0052821,000,000
ストリング連結100,0004370.0043711250.011252288895
テンプレートを適用10,0005000.056100.061590000
V8 BS-リチャーズ259812392.4810031401.240
V8 BS-暗号化102719271.93469346.90
V8 BS-復号化5281405628282975659.40
V8 BS-正規表現10344373443.7330163301.60

JSDB 1.8.0.3
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,0003430.0003437190.0007191,000,000
ストリング連結100,0007030.007035470.005472288895
テンプレートを適用10,0003830.03832330.0233590000
V8 BS-リチャーズ10004831948.3194994849.9480
V8 BS-暗号化1090590.592592.50
V8 BS-復号化10165711657.1164751647.50
V8 BS-正規表現10159681596.8136361363.60

Microsoft JScript 5.6.8825
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00025780.00257858120.0058121,000,000
ストリング連結100,00045310.0453148440.048442288895
テンプレートを適用10,00013440.134413750.1375410000
V8 BS-リチャーズ10018484184.8418422184.220
V8 BS-暗号化101813181.31797179.70
V8 BS-復号化10325003250321873218.70
V8 BS-正規表現10379383793.8375473754.70

Microsoft JScript 5.7.16599
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00042350.00423565620.0065621,000,000
ストリング連結100,00016250.0162519690.019692288895
テンプレートを適用10,0005620.05625940.0594410000
V8 BS-リチャーズ10022328223.2822625226.250
V8 BS-暗号化101797179.71813181.30
V8 BS-復号化10339533395.3322193221.90
V8 BS-正規表現10278132781.3296092960.90

Microsoft JScript 5.8.18702
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,00011710.00117115320.0015321,000,000
ストリング連結100,0008440.0084412350.012352288895
テンプレートを適用10,0003590.03593590.0359410000
V8 BS-リチャーズ10011906119.0612094120.940
V8 BS-暗号化1016101611578157.80
V8 BS-復号化10268752687.5272812728.10
V8 BS-正規表現10227812278.1223912239.10



Windows 7での結果の完全な表。
NodeJS v 0.2.4
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,000120.000012140.0000141,000,000
ストリング連結100,000170.00017130.000132288895
テンプレートを適用10,00090.0009110.0011590000
V8 BS-リチャーズ100016401.6417491.7490
V8 BS-暗号化1001201.21281.280
V8 BS-復号化100257025.7257325.730
V8 BS-正規表現100399639.96399639.960

JSDB 1.8.0.3
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,000890.0000892210.0002211,000,000
ストリング連結100,0001770.001771670.001672288895
テンプレートを適用10,000330.0033330.0033590000
V8 BS-リチャーズ10001773817.7381778017.780
V8 BS-暗号化1027227.227627.60
V8 BS-復号化105095509.55103510.30
V8 BS-正規表現103454345.43499349.90

Microsoft .NET v.4.0.30319.1
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,0005740.00057413440.0013441,000,000
ストリング連結100,0001490.001493340.003342288895
テンプレートを適用10,0001400.0142810.0281590000
V8 BS-リチャーズ25226890.722576103.040
V8 BS-暗号化1047147.12813281.30
V8 BS-復号化54908981.650181003.60
V8 BS-正規表現108762876.28805880.50

Microsoft .NET v.4.0.30319.1
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,0005160.00051612930.0012931,000,000
ストリング連結100,0001180.001182730.002732288895
テンプレートを適用10,0001360.01363010.0301590000
V8 BS-リチャーズ25218887.52247799.080
V8 BS-暗号化104704730003000
V8 BS-復号化54831966.250491009.80
V8 BS-正規表現108704870.48826882.60

Microsoft JScript 5.8.16475
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,0002440.0002445020.0005021,000,000
ストリング連結100,0001680.001682240.002242288895
テンプレートを適用10,000900.009950.0095410000
V8 BS-リチャーズ100439143.914400440
V8 BS-暗号化1061161.161961.90
V8 BS-復号化10105021050.2105121051.20
V8 BS-正規表現104768476.84772477.20

Microsoft JScript 9.0.16406
お名前ループ時間平均時間平均wr解像度
空のテスト1,000,000410.000041820.0000821,000,000
ストリング連結100,000380.00038390.000392288895
テンプレートを適用10,000180.0018170.0017590000
V8 BS-リチャーズ1001661.661661.660
V8 BS-暗号化10151.5373.70
V8 BS-復号化1025325.324624.60
V8 BS-正規表現103175317.53188318.80


結論


.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の時間と各テストの時間の比率をとり、テスト全体で平均しました。

評価エンジン(詳細-より良い)


参照:

NodeJS
Jsdb
Google V8 Benchmark Suiteバージョン6
Microsoft Windowsスクリプトホスト
Microsoft jscript

Source: https://habr.com/ru/post/J108760/


All Articles