• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Test the speed of .pipe() with sockets
2'use strict';
3
4const common = require('../common.js');
5const net = require('net');
6const PORT = common.PORT;
7
8const bench = common.createBenchmark(main, {
9  len: [64, 102400, 1024 * 1024 * 16],
10  type: ['utf', 'asc', 'buf'],
11  dur: [5],
12}, {
13  test: { len: 1024 }
14});
15
16let chunk;
17let encoding;
18
19function main({ dur, len, type }) {
20  switch (type) {
21    case 'buf':
22      chunk = Buffer.alloc(len, 'x');
23      break;
24    case 'utf':
25      encoding = 'utf8';
26      chunk = 'ü'.repeat(len / 2);
27      break;
28    case 'asc':
29      encoding = 'ascii';
30      chunk = 'x'.repeat(len);
31      break;
32    default:
33      throw new Error(`invalid type: ${type}`);
34  }
35
36  const reader = new Reader();
37  const writer = new Writer();
38
39  // The actual benchmark.
40  const server = net.createServer((socket) => {
41    socket.pipe(writer);
42  });
43
44  server.listen(PORT, () => {
45    const socket = net.connect(PORT);
46    socket.on('connect', () => {
47      bench.start();
48
49      reader.pipe(socket);
50
51      setTimeout(() => {
52        const bytes = writer.received;
53        const gbits = (bytes * 8) / (1024 * 1024 * 1024);
54        bench.end(gbits);
55        process.exit(0);
56      }, dur * 1000);
57    });
58  });
59}
60
61function Writer() {
62  this.received = 0;
63  this.writable = true;
64}
65
66Writer.prototype.write = function(chunk, encoding, cb) {
67  this.received += chunk.length;
68
69  if (typeof encoding === 'function')
70    encoding();
71  else if (typeof cb === 'function')
72    cb();
73
74  return true;
75};
76
77// Doesn't matter, never emits anything.
78Writer.prototype.on = function() {};
79Writer.prototype.once = function() {};
80Writer.prototype.emit = function() {};
81Writer.prototype.prependListener = function() {};
82
83
84function flow() {
85  const dest = this.dest;
86  const res = dest.write(chunk, encoding);
87  if (!res)
88    dest.once('drain', this.flow);
89  else
90    process.nextTick(this.flow);
91}
92
93function Reader() {
94  this.flow = flow.bind(this);
95  this.readable = true;
96}
97
98Reader.prototype.pipe = function(dest) {
99  this.dest = dest;
100  this.flow();
101  return dest;
102};
103