• 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: [2, 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(socket);
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      socket.pipe(writer);
51
52      setTimeout(() => {
53        // Multiply by 2 since we're sending it first one way
54        // then back again.
55        const bytes = writer.received * 2;
56        const gbits = (bytes * 8) / (1024 * 1024 * 1024);
57        bench.end(gbits);
58        process.exit(0);
59      }, dur * 1000);
60    });
61  });
62}
63
64function Writer() {
65  this.received = 0;
66  this.writable = true;
67}
68
69Writer.prototype.write = function(chunk, encoding, cb) {
70  this.received += chunk.length;
71
72  if (typeof encoding === 'function')
73    encoding();
74  else if (typeof cb === 'function')
75    cb();
76
77  return true;
78};
79
80// Doesn't matter, never emits anything.
81Writer.prototype.on = function() {};
82Writer.prototype.once = function() {};
83Writer.prototype.emit = function() {};
84Writer.prototype.prependListener = function() {};
85
86
87function flow() {
88  const dest = this.dest;
89  const res = dest.write(chunk, encoding);
90  if (!res)
91    dest.once('drain', this.flow);
92  else
93    process.nextTick(this.flow);
94}
95
96function Reader() {
97  this.flow = flow.bind(this);
98  this.readable = true;
99}
100
101Reader.prototype.pipe = function(dest) {
102  this.dest = dest;
103  this.flow();
104  return dest;
105};
106