ServerSide Speed ​​Test

Recently, JavaScript engine performance tests have become very popular, but they mainly concern Client Side JavaScript. I was interested in the question: how are things going with Server Side? But testing only Google V8 and SpiderMonkey would be uninteresting. It is clear that the results will be similar to those of 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, and also try to use tests specific to server tasks. This missing test object was seen by 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 100% objectivity of the tests. The goal was to test engines that are accessible at arm's length (5 minutes of googling) and in the environment that is accessible 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, obtaining the result lasted for several days.

Testing methodology


A simple testing methodology was chosen. Each test is a certain function that is launched to execute in a loop a large number of times. The execution time of the entire cycle is measured. The average execution time of each iteration is taken as an evaluation criterion. I did not follow the principles of statistical reliability - run tests several times in a row and calculate the average deviations. This approach, in my opinion, requires a deeper analysis than just running the tests several times and calculating the average deviations.
In order to evaluate how much time the test itself takes in the test, the first test will be an empty function. In addition, in the light of recent trends that are associated with technology for removing dead code, I wanted to somehow take this factor into account in tests. It never occurred to me any better than setting the requirement for the tested functions to return a certain result, which is based on what a particular function does. Thus, the cunning optimization techniques, I hope, will not have a reason to throw the "necessary" code. Naturally, cunning optimization can throw out code on the basis that the result of the function is not used further. Therefore, I added an additional parameter to each tested function - a function for aggregating the results. The aggregated result itself will also be the result of the test. To assess the effect of aggregation itself on the result of the cycle, I ran it again without aggregation. It also helps to subjectively assess whether there is optimization for eliminating dead code.
For the convenience of running tests and processing the results, I wrote a small framework. In addition, for the uniform output of test results for each engine, its own adapter module was used. The results were formatted in html, displayed on the console, and accumulated in a single file through thread redirection.
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 that runs on Google Chrome, and is presented in the test in the form of no less 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 hope for any significant differences from Client Side tests.
The third player is Microsoft's JavaScript compiler. I was wondering what benefit the use of the compiler gives compared to interpreters.
Fourth player - for a more complete comparison, it would be nice to use another interpreter from Microsoft.

In case of testing the interpreters, I simply merged all test files, the framework and adapters into one file with the copy command, fed the resulting file 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 represented by cscript.exe utility.
For the compiler, all files were fed by jsc.exe from the corresponding version of the .Net Framework and the resulting exe file was launched.

The recruitment of players on each platform 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
  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
  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 used in IE9. I had to do a little magic to make it work in Windows Script Host without installing IE9 itself. I don’t even know if it will be available in WSH after installation, since the library in the installation package is called differently and next to it lies the old engine from IE 8, with a normal name.
Under Windows 7, I still had access to the compiler from .NET v.2.0, but the test under it for some reason fell out with an error, details later.
I used different versions of the engines from Microsoft 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 tested function and the results for the average cycle time for all engines. Then all 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 test function, reduce is the aggregator function, start is the start value of the aggregator, loops is the number of cycles in the test.

Empty test results on Windows XP (less is better) Empty test results on Windows 7 (less is better)







String concatenation


A test of a typical string operation.

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 a template with data



In my opinion, a typical server operation.

   var template = '{title}{main}';
  
  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.


Apply template results on Windows XP (less is better) Apply template results on Windows 7 (less is better) The following tests I took from Google V8 Benchmark Suite version 6 . Unfortunately, it turned out that these tests are full of errors. The errors were pointed out to me by the JScript compiler. Some errors were related to incomplete compatibility of JScript and JavaScript. Part really was a mistake. I took 3 tests that created the least problems. I adapted it a bit to my framework, fixed errors. One could take tests from Sunspider, but, unfortunately, I did not find them in the form of convenient js sources. The version presented on the site with the test requires processing by the parser, because it is built into html. I will not give here the sources of these tests - only the results.










V8 Benchmark Suite Richards


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

V8 BS Results - Richards on Windows XP (Less is Better) V8 BS Results - Richards on Windows 7 (Less is Better)






V8 Benchmark Suite Encrypt


Data encoding.

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.

V8 BS Results - Decrypt on Windows XP (Less is Better) V8 BS Results - Decrypt on Windows 7 (Less is Better)





V8 Benchmark Suite RegExp


Regular expressions extracted from 50 popular sites on the Internet.

Results of V8 BS - RegExp on Windows XP (less is better) Results of V8 BS - RegExp on Windows 7 (less is better) Complete table of results 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 - Richards 100048794.87947024.7020
V8 BS - Encrypt 1003453.453563.560
V8 BS - Decrypt 100749674.96751475.140
V8 BS - Regexp 10011620116.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 - Richards 259266370.649390375.60
V8 BS - Encrypt 102875287.53062306.20
V8 BS - Decrypt 5336576731.4320786415.60
V8 BS - Regexp 10322963229.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 - Richards 259703388.129859394.360
V8 BS - Encrypt 102531253.12875287.50
V8 BS - Decrypt 5253445068.8250475009.40
V8 BS - Regexp 10290322903.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 - Richards 259812392.4810031401.240
V8 BS - Encrypt 102719271.93469346.90
V8 BS - Decrypt 5281405628282975659.40
V8 BS - Regexp 10344373443.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 - Richards 10004831948.3194994849.9480
V8 BS - Encrypt 1090590.592592.50
V8 BS - Decrypt 10165711657.1164751647.50
V8 BS - Regexp 10159681596.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 - Richards 10018484184.8418422184.220
V8 BS - Encrypt 101813181.31797179.70
V8 BS - Decrypt 10325003250321873218.70
V8 BS - Regexp 10379383793.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 - Richards 10022328223.2822625226.250
V8 BS - Encrypt 101797179.71813181.30
V8 BS - Decrypt 10339533395.3322193221.90
V8 BS - Regexp 10278132781.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 - Richards 10011906119.0612094120.940
V8 BS - Encrypt 1016101611578157.80
V8 BS - Decrypt 10268752687.5272812728.10
V8 BS - Regexp 10227812278.1223912239.10



Complete results table on Windows 7.
NodeJS v 0.2.4
NameLoopsTimeAvgTime wrAvg wrRes
Empty test1,000,000120.000012140.0000141,000,000
String concat100,000170.00017thirteen0.000132288895
Apply template10,00090.0009eleven0.0011590000
V8 BS - Richards 100016401.6417491.7490
V8 BS - Encrypt 1001201.21281.280
V8 BS - Decrypt 100257025.7257325.730
V8 BS - Regexp 100399639.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 - Richards 10001773817.7381778017.780
V8 BS - Encrypt 1027227.227627.60
V8 BS - Decrypt 105095509.55103510.30
V8 BS - Regexp 103454345.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 - Richards 25226890.722576103.040
V8 BS - Encrypt 1047147.12813281.30
V8 BS - Decrypt 54908981.650181003.60
V8 BS - Regexp 108762876.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 - Richards 25218887.52247799.080
V8 BS - Encrypt 104704730003000
V8 BS - Decrypt 54831966.250491009.80
V8 BS - Regexp 108704870.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 - Richards 100439143.914400440
V8 BS - Encrypt 1061161.161961.90
V8 BS - Decrypt 10105021050.2105121051.20
V8 BS - Regexp 104768476.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 - Richards 1001661.661661.660
V8 BS - Encrypt 10fifteen1.5373.70
V8 BS - Decrypt 1025325.324624.60
V8 BS - Regexp 103175317.53188318.80


conclusions


The .NET compiler (more precisely, the results of its work) turned out to be the slowest. Either I'm doing something wrong, or he is just not good at anything. Interpreter from Microsoft versions less than 9th failed the test for the use of the template - the result is different from the rest. A closer examination showed that it differs in the assignment of the parameters of the callback function to replace.
Under Windows 7, it was not possible to test the compiler version 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 consumed up to 6 GB of memory. Why did the tests themselves show not such catastrophic times? A closer look at the problem revealed a strange feature of the compiler for Windows 7 x64: the V8 BS - Regexp test created the problems. Moreover, the compiled program began to devour memory even before the start of my code execution. It seems .Net somehow initializes regular expressions, which are abundant in this test, even before the code runs. Moreover, problems are observed if the regular expressions are in the function that creates the closure.
My final conclusion is this: the JScript compiler from the .NET Framework is good for nothing but testing the code for compilation errors. It also became interesting for me to test how C # will differ in such tasks. However, the “speedy” failure of JScript .NET begins to become clearer when you look at the stack trace when displaying error messages. I have not seen so many wrappers on simple calls.
However, the new interpreter from Microsoft JScript 9.0 is quite competitive, it is easy to extend its classes through ActiveScripting. Interesting is the choice of version. Why, after version 5.8, which was used in IE8, version 9.0 suddenly came out? However, after the official release, everything may change.
Leader in Google V8 shortness in NodeJS, but JScript 9.0 is on its 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 the factors. Including the convenience of expansion, debugging, integration with the platform.

And at the end - a meaningless, purely illustrative diagram. I just took the ratio of NodeJS time to the time of each test and averaged over the tests. Engine

rating (more is better) Links: NodeJS JSDB Google V8 Benchmark Suite version 6 Microsoft Windows Script Host Microsoft JScript










Also popular now: