📜 ⬆️ ⬇️

ServerSide speed test

Recently, JavaScript engine performance tests have become very popular, but they mainly concern the Client Side JavaScript. I was interested in the question: how are things with Server Side? But testing only Google V8 and SpiderMonkey would be uninteresting. It is clear that the results will be similar to the Client Side - the engines are the same. Therefore, it was necessary to add to the tests something that is not available in the browser, but it is quite common, as well as try to use tests specific to server tasks. This missing test object was the JScript compiler from the .Net Framework. However, the preliminary test results came as a surprise to me, and I decided to add a fourth player from the same team.

.

First of all, it should be said that I did not set the goal of a 100% objective test. The goal was to test the engines that are available at arm's length (5 minutes of googling) and in the environment that is available to me. And this:
')
Windows XP SP3 on AMD Sempron 2800+ 1.6GHz 1Gb RAM
Windows 7 x64 on Intel Core i5 650 3.2GHz 4Gb RAM

Despite the simplicity of the tasks, the result was stretched for several days.

Testing method


A simple testing methodology was chosen. Each test is a function that runs on a loop a large number of times. The runtime of the entire cycle is measured. The average execution time for each iteration is taken as an evaluation criterion. I did not follow the principles of statistical accuracy - run the tests several times in a row and calculate the average deviations. This approach, in my opinion, requires a deeper analysis than just running tests several times and calculating the mean deviations.
In order to estimate how long the cycle itself takes in the test, the first test will be an empty function. In addition, in the light of recent trends that are related to the technology of removing dead code, I wanted to somehow take this factor into account in the tests. It did not occur to me to do anything better than to set the requirement for the functions under test to return a certain result, which is based on what a particular function does. Thus, I hope, tricky optimization techniques will have no reason to throw out the “necessary” code. Naturally, tricky optimization can throw out the code on the grounds that the result of the function is not used further. Therefore, I added an additional parameter to each tested function - a function for aggregating results. The aggregate result itself will also be the result of the test. To assess the impact of the aggregation itself on the result of the cycle, I ran it again without aggregation. It also helps to subjectively assess the presence of optimization for eliminating dead code.
For the convenience of running tests and processing the results, I wrote a small framework. In addition, for a uniform output of test results for each engine, its own adapter module was used. The results were formatted in html, output to the console and accumulated in a single file through the redirection of threads.
To run the entire test a small set of CMD files was used.

Players


The first player is a promising and increasingly popular Google V8 engine, which works in Google Chrome, and is presented in the test in the face of the equally promising NodeJS . I was sure that the test results would not disappoint me.
The second player is a fairly fast engine with a rich history - SpiderMonkey, which works in FireFox, in tests it worked on behalf of JSDB . Here, I also did not expect any significant differences from the Client Side tests.
The third player is the Microsoft JavaScript compiler. I was wondering what kind of gains the use of the compiler gives compared to interpreters.
The fourth player - for a more complete comparison, it would be good to use another interpreter from Microsoft.

In the case of interpreter testing, I simply merged all the test files, frameworks and adapters into one file with the copy command, the resulting file fed to the interpreter. For NodeJS it is nodejs.exe, for JSDB it is jsdb.exe, for the interpreter from Microsoft it is Windows Script Host in the face of the utility cscript.exe.
For the compiler, all the files were fed jsc.exe from the corresponding version of the .Net Framework and the resulting exe file was launched.

The set of players on each of the platforms was different.

Windows xp


  1. NodeJS v 0.2.4
  2. JSDB 1.8.0.3
  3. Microsoft JScript 5.6.8825 interpreter
  4. Microsoft JScript 5.7.16599 interpreter
  5. Microsoft JScript 5.8.18702 interpreter
  6. JScript compiler from Microsoft .NET v.1.1.4322.2032
  7. JScript compiler from Microsoft .NET v.2.0.50727.3053
  8. JScript compiler from Microsoft .NET v.4.0.30319.1


Windows 7


  1. NodeJS v 0.2.4
  2. JSDB 1.8.0.3
  3. Microsoft JScript 5.8.16475 interpreter
  4. Microsoft JScript 9.0.16406 interpreter
  5. JScript compiler from Microsoft .NET v.4.0.30319.1


Yes. I was not mistaken. Microsoft JScript 9.0.16406 is the very engine that is used in IE9. I had to conjure a little to make it work in Windows Script Host without installing IE9 itself. I do not even know whether it will be available in WSH after installation, since the library in the installation package is called differently and next to it is the old IE 8 engine, with the normal name.
Under Windows 7, the compiler from .NET v.2.0 was still available to me, but for some reason the test under it fell out with an error, details later.
I used different versions of Microsoft's engines to see if there is any progress in speed from version to version and which one. They lay under my feet. Why not include them in the test?

Tests



Further, for each test I will give the test function and the results for the average cycle time for all engines. Then all the test results at the end.

Empty function



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 .


here func is the function under test, reduce is the aggregator function, start is the starting value of the aggregator, loops is the number of cycles in the test.

Results of an empty test on Windows XP (less is better)



Results of an empty test on Windows 7 (less is better)



String concatenation


Typical string operation test.

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 .


String Concat results on Windows XP (less is better)


String Concat results on Windows 7 (less is better)


Filling the template with data



In my opinion typical operation for the server.

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 .


Results of the Apply template on Windows XP (less is better)


Results of the Apply template on Windows 7 (less is better)


I took the following tests from Google V8 Benchmark Suite version 6 .

Unfortunately, it turned out that these tests are full of errors. The errors I pointed out to the JScript compiler. Part of the error was due to incomplete JScript and JavaScript compatibility. The piece really was a mistake. I took 3 tests that created the least problems. Adapted a little for my framework, corrected errors. It would be possible to take tests from Sunspider, but, unfortunately, I did not find them in the form of convenient js source. The version presented on the site with the test requires processing by the parser, since it is embedded in the html.
I will not give here the source of these tests - only the results.

V8 Benchmark Suite Richards


As stated on the site, simulates the operation of the OS kernel.

V8 BS - Richards results on Windows XP (less is better)


V8 BS - Richards results on Windows 7 (less is better)



V8 Benchmark Suite Encrypt


Encoding data.

Results V8 BS - Encrypt on Windows XP (less is better)


Results V8 BS - Encrypt on Windows 7 (less is better)


V8 Benchmark Suite Decrypt


Decoding data.

Results V8 BS - Decrypt on Windows XP (less is better)


Results V8 BS - Decrypt on Windows 7 (less is better)


V8 Benchmark Suite RegExp


Regular expressions extracted from 50 popular sites on the Internet.

Results V8 BS - RegExp on Windows XP (less is better)


Results V8 BS - RegExp on Windows 7 (less is better)


Complete results table on Windows XP.
NodeJS v 0.2.4
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,000210.000021440.0000441,000,000
String concat100,000440.00044470.000472288895
Apply template10,000320.0032280.0028590000
V8 BS - Richards100048794.87947024.7020
V8 BS - Encrypt1003453.453563.560
V8 BS - Decrypt100749674.96751475.140
V8 BS - Regexp10011620116.211913119.130

Microsoft .NET v.1.1.4322.2032
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00018910.00189140940.0040941,000,000
String concat100,0003440.003448590.008592288895
Apply template10,0005320.05326090.0609590000
V8 BS - Richards259266370.649390375.60
V8 BS - Encryptten2875287.53062306.20
V8 BS - Decryptfive336576731.4320786415.60
V8 BS - Regexpten322963229.6332193321.90

Microsoft .NET v.2.0.50727.3053
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00033280.00332885780.0085781,000,000
String concat100,0005150.0051512970.012972288895
Apply template10,0005470.05476570.0657590000
V8 BS - Richards259703388.129859394.360
V8 BS - Encryptten2531253.12875287.50
V8 BS - Decryptfive253445068.8250475009.40
V8 BS - Regexpten290322903.2292342923.40

Microsoft .NET v.4.0.30319.1
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00021880.00218852820.0052821,000,000
String concat100,0004370.0043711250.011252288895
Apply template10,0005000.056100.061590000
V8 BS - Richards259812392.4810031401.240
V8 BS - Encryptten2719271.93469346.90
V8 BS - Decryptfive281405628282975659.40
V8 BS - Regexpten344373443.7330163301.60

JSDB 1.8.0.3
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,0003430.0003437190.0007191,000,000
String concat100,0007030.007035470.005472288895
Apply template10,0003830.03832330.0233590000
V8 BS - Richards10004831948.3194994849.9480
V8 BS - Encryptten90590.592592.50
V8 BS - Decryptten165711657.1164751647.50
V8 BS - Regexpten159681596.8136361363.60

Microsoft JScript 5.6.8825
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00025780.00257858120.0058121,000,000
String concat100,00045310.0453148440.048442288895
Apply template10,00013440.134413750.1375410000
V8 BS - Richards10018484184.8418422184.220
V8 BS - Encryptten1813181.31797179.70
V8 BS - Decryptten325003250321873218.70
V8 BS - Regexpten379383793.8375473754.70

Microsoft JScript 5.7.16599
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00042350.00423565620.0065621,000,000
String concat100,00016250.0162519690.019692288895
Apply template10,0005620.05625940.0594410000
V8 BS - Richards10022328223.2822625226.250
V8 BS - Encryptten1797179.71813181.30
V8 BS - Decryptten339533395.3322193221.90
V8 BS - Regexpten278132781.3296092960.90

Microsoft JScript 5.8.18702
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,00011710.00117115320.0015321,000,000
String concat100,0008440.0084412350.012352288895
Apply template10,0003590.03593590.0359410000
V8 BS - Richards10011906119.0612094120.940
V8 BS - Encryptten16101611578157.80
V8 BS - Decryptten268752687.5272812728.10
V8 BS - Regexpten227812278.1223912239.10



Full results table for Windows 7.
NodeJS v 0.2.4
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,000120.000012140.0000141,000,000
String concat100,000170.00017130.000132288895
Apply template10,00090.0009eleven0.0011590000
V8 BS - Richards100016401.6417491.7490
V8 BS - Encrypt1001201.21281.280
V8 BS - Decrypt100257025.7257325.730
V8 BS - Regexp100399639.96399639.960

JSDB 1.8.0.3
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,000890.0000892210.0002211,000,000
String concat100,0001770.001771670.001672288895
Apply template10,000330.0033330.0033590000
V8 BS - Richards10001773817.7381778017.780
V8 BS - Encryptten27227.227627.60
V8 BS - Decryptten5095509.55103510.30
V8 BS - Regexpten3454345.43499349.90

Microsoft .NET v.4.0.30319.1
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,0005740.00057413440.0013441,000,000
String concat100,0001490.001493340.003342288895
Apply template10,0001400.0142810.0281590000
V8 BS - Richards25226890.722576103.040
V8 BS - Encryptten47147.12813281.30
V8 BS - Decryptfive4908981.650181003.60
V8 BS - Regexpten8762876.28805880.50

Microsoft .NET v.4.0.30319.1
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,0005160.00051612930.0012931,000,000
String concat100,0001180.001182730.002732288895
Apply template10,0001360.01363010.0301590000
V8 BS - Richards25218887.52247799.080
V8 BS - Encryptten4704730003000
V8 BS - Decryptfive4831966.250491009.80
V8 BS - Regexpten8704870.48826882.60

Microsoft JScript 5.8.16475
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,0002440.0002445020.0005021,000,000
String concat100,0001680.001682240.002242288895
Apply template10,000900.009950.0095410000
V8 BS - Richards100439143.914400440
V8 BS - Encryptten61161.161961.90
V8 BS - Decryptten105021050.2105121051.20
V8 BS - Regexpten4768476.84772477.20

Microsoft JScript 9.0.16406
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,000410.000041820.0000821,000,000
String concat100,000380.00038390.000392288895
Apply template10,000180.0018170.0017590000
V8 BS - Richards1001661.661661.660
V8 BS - Encryptten151.5373.70
V8 BS - Decryptten25325.324624.60
V8 BS - Regexpten3175317.53188318.80


findings


The .NET compiler (more precisely, the results of its work) was the slowest. Either I am doing something wrong, or he is simply not good for anything. The interpreter from Microsoft versions less than the 9th failed the test for using the template - the result is different from the others. A closer look revealed that there are different assignments to the parameters of the callback function for replace.
Under Windows 7, it was not possible to test the version of the compiler from the .NET Framework 2.0, and version 4.0 behaved no less strange. The test worked for 20 minutes. Version 2.0 crashed with an error. For both versions, the test ate up to 6 GB of memory. Why did the tests themselves show not such disastrous times? A closer examination of the problem revealed a strange feature of the compiler for Windows 7 x64: the problems were created by the V8 BS test - Regexp. And the compiled program started to devour the memory even before the beginning of the execution of my code. It seems that .Net somehow initializes regular expressions, which are abundant in this test, even before the code is executed. Moreover, problems are observed if regular expressions are in a function that creates a closure.
My final conclusion is: the JScript compiler from the .NET Framework is good for nothing, except for testing the code for compilation errors. It also became interesting for me to test how C # will differ on similar tasks. However, the “high-speed” failure of JScript .NET starts to clear up if you look at the stack trace when displaying error messages. I have not seen such a large number of wrappers on simple calls.
However, the new interpreter from Microsoft JScript 9.0 is quite competitive, it is easy to extend it with its classes through ActiveScripting. The choice of the version seems interesting. Why after version 5.8, which was used in IE8, did version 9.0 suddenly come out? However, after the official release, everything can change.
The leader in terms of Google V8 is NodeJS, but JScript 9.0 comes on the heels. It seems to me that the final choice can be safely made not only by the criterion of speed, but by the sum of factors. Including on convenience of expansion, debugging, integration with the platform.

And in the end - nothing meaningful, purely illustrative diagram. I just took the ratio of NodeJS time to the time of each test and averaged over the tests.

Rating engines (more - better)


References:

Nodejs
Jsdb
Google V8 Benchmark Suite version 6
Microsoft Windows Script Host
Microsoft JScript

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


All Articles