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