I try so send nodejs Buffers via node:net Server and Socket. That works fine in principle.
But when I re-create the Buffer on the receiver side using Buffer.concat(), this is really slow. Expected: when doubling the Buffer size, I would expect the process to take roughly twice as long. The "overall speed" (bytes per second) would be roughly constant. Observed: for a 5MB Buffer, it takes 0.1 seconds; for a 50MB, it takes 10 seconds.
It there anything I could do better?
The test code is: (socketSpeed.js)
const { Socket, Server } = require('node:net');
const server = process.argv[2] === 'server'
const client = process.argv[2] === 'client';
const address = process.argv[3];
const port = process.argv[4];
const mbToSend = process.argv[5];
if (server) {
const serverOpts = {
keepAlive: true,
keepAliveInitialDelay: 3000,
};
socketServer = new Server(serverOpts);
socketServer.on('connection', (socket) => {
console.log('Server connected');
socket.on('data', async (data) => {
console.log('Server input: ' + data.toString());
});
socket.on('error', async (error) => {
console.log('Server error: ' + error);
});
socket.on('end', async () => {
console.log('Server end reached: ');
});
// here: send some data...
console.log(`Sending ${mbToSend} MB.`);
socket.write(Buffer.from('x'.repeat( mbToSend * 1024 * 1024))); // 10 MB
socket.end();
socketServer.close();
});
const options = {
port: port,
host: address,
};
socketServer.listen(options);
} else if (client) {
const socketClient = new Socket();
const options = {
port: port,
host: address,
};
socketClient.on('connection', (socket) => {
console.log('Client connected');
});
socketClient.connect(options);
let dataReceived = 0;
let allData = undefined;
const start = Date.now();
socketClient.on('data', async (data) => {
dataReceived += data.length;
// ----------------------------
// This data collection below using Buffer.concat causes the slow-down!
// ----------------------------
if (allData === undefined) allData = data;
else allData = Buffer.concat([allData, data]);
});
socketClient.on('error', async (error) => {
console.log('Client error: ' + error);
});
socketClient.on('end', async () => {
const end = Date.now();
const time = (end - start) / 1000;
console.log(`Client end reached, got ${dataReceived / 1024/1024} MB in ${time} seconds.`);
console.log(` speed: ${dataReceived/1024/1024 / time} MB/s`);
});
} else {
console.log('run thes in 2 different terminals:');
console.log(' node socketSpeed.js server localhost 34567 10)');
console.log(' node socketSpeed.js client localhost 34567');
}
Just run in 2 shells node socketSpeed.js server localhost 34567 10 (the 10 means, that one 10 MB Buffer is sent from the server to the client) node socketSpeed.js client localhost 34567
Buffer.concatat the end of the connection, instead of concat every chunk and override "allDate" every time?