revise installing a license file
[platform/upstream/nodejs.git] / benchmark / http_simple_auto.js
1 //
2 // Usage:
3 //   node benchmark/http_simple_auto.js <args> <target>
4 //
5 // Where:
6 //   <args>   Arguments to pass to `ab`.
7 //   <target> Target to benchmark, e.g. `bytes/1024` or `buffer/8192`.
8 //
9 'use strict';
10
11 var http = require('http');
12 var spawn = require('child_process').spawn;
13
14 var port = parseInt(process.env.PORT || 8000);
15
16 var fixed = 'C'.repeat(20 * 1024);
17
18 var stored = {};
19 var storedBuffer = {};
20
21 var server = http.createServer(function(req, res) {
22   var commands = req.url.split('/');
23   var command = commands[1];
24   var body = '';
25   var arg = commands[2];
26   var n_chunks = parseInt(commands[3], 10);
27   var status = 200;
28   var n;
29   var i;
30
31   if (command == 'bytes') {
32     n = parseInt(arg, 10);
33     if (n <= 0)
34       throw new Error('bytes called with n <= 0');
35     if (stored[n] === undefined) {
36       stored[n] = 'C'.repeat(n);
37     }
38     body = stored[n];
39   } else if (command == 'buffer') {
40     n = parseInt(arg, 10);
41     if (n <= 0) throw new Error('bytes called with n <= 0');
42     if (storedBuffer[n] === undefined) {
43       storedBuffer[n] = new Buffer(n);
44       for (i = 0; i < n; i++) {
45         storedBuffer[n][i] = 'C'.charCodeAt(0);
46       }
47     }
48     body = storedBuffer[n];
49
50   } else if (command == 'quit') {
51     res.connection.server.close();
52     body = 'quitting';
53
54   } else if (command == 'fixed') {
55     body = fixed;
56
57   } else if (command == 'echo') {
58     res.writeHead(200, { 'Content-Type': 'text/plain',
59                          'Transfer-Encoding': 'chunked' });
60     req.pipe(res);
61     return;
62
63   } else {
64     status = 404;
65     body = 'not found\n';
66   }
67
68   // example: http://localhost:port/bytes/512/4
69   // sends a 512 byte body in 4 chunks of 128 bytes
70   if (n_chunks > 0) {
71     res.writeHead(status, { 'Content-Type': 'text/plain',
72                             'Transfer-Encoding': 'chunked' });
73     // send body in chunks
74     var len = body.length;
75     var step = Math.floor(len / n_chunks) || 1;
76
77     for (i = 0, n = (n_chunks - 1); i < n; ++i) {
78       res.write(body.slice(i * step, i * step + step));
79     }
80     res.end(body.slice((n_chunks - 1) * step));
81   } else {
82     var content_length = body.length.toString();
83
84     res.writeHead(status, { 'Content-Type': 'text/plain',
85                             'Content-Length': content_length });
86     res.end(body);
87   }
88
89 });
90
91 server.listen(port, function() {
92   var url = 'http://127.0.0.1:' + port + '/';
93
94   var n = process.argv.length - 1;
95   process.argv[n] = url + process.argv[n];
96
97   var cp = spawn('ab', process.argv.slice(2));
98   cp.stdout.pipe(process.stdout);
99   cp.stderr.pipe(process.stderr);
100   cp.on('exit', function() {
101     server.close();
102     process.nextTick(dump_mm_stats);
103   });
104 });
105
106 function dump_mm_stats() {
107   if (typeof global.gc != 'function') return;
108
109   var before = process.memoryUsage();
110   for (var i = 0; i < 10; ++i) global.gc();
111   var after = process.memoryUsage();
112   setTimeout(print_stats, 250); // give GC time to settle
113
114   function print_stats() {
115     console.log('\nBEFORE / AFTER GC');
116     ['rss', 'heapTotal', 'heapUsed'].forEach(function(key) {
117       var a = before[key] / (1024 * 1024);
118       var b = after[key] / (1024 * 1024);
119       console.log('%sM / %sM %s', a.toFixed(2), b.toFixed(2), key);
120     });
121   }
122 }