uNetworking / uWebSockets.js

μWebSockets for Node.js back-ends :metal:
Apache License 2.0
8.09k stars 578 forks source link

Slowness problem #1083

Closed yigit433 closed 3 months ago

yigit433 commented 3 months ago

Hello, as you can see in the screenshot I sent as a result of the tests I made, the fastest one is the ws module. image I used the libraries I used in the test in their most basic form. Maybe there is a deficiency in the configuration, what is your solution for this problem?

index.js

const WebSocket = require('ws');
const io = require('socket.io-client');

function runTest(serverUrl, messageCount, messageSize, protocol) {
    return new Promise((resolve) => {
        const messages = Array(messageCount).fill('A'.repeat(messageSize));
        const startTime = Date.now();
        let receivedCount = 0;

        let ws;
        if (protocol === 'ws' || protocol === 'uWS') {
            ws = new WebSocket(serverUrl);
        } else if (protocol === 'socket.io') {
            ws = io(serverUrl);
        }

        ws.onopen = () => {
            messages.forEach((message) => ws.send(message));
        };

        ws.onmessage = () => {
            receivedCount += 1;
            if (receivedCount === messageCount) {
                const endTime = Date.now();
                const duration = endTime - startTime;
                resolve(duration);
                ws.close();
            }
        };

        if (protocol === 'socket.io') {
            ws.on('connect', ws.onopen);
            ws.on('message', ws.onmessage);
        }
    });
}

async function main() {
    const messageCount = 1000;
    const messageSize = 100;

    console.log('Testing uWebSockets.js...');
    const uWSTime = await runTest('ws://localhost:9001', messageCount, messageSize, 'uWS');
    console.log(`uWebSockets.js: ${uWSTime} ms`);

    console.log('Testing ws...');
    const wsTime = await runTest('ws://localhost:9002', messageCount, messageSize, 'ws');
    console.log(`ws: ${wsTime} ms`);

    console.log('Testing Socket.io...');
    const socketIoTime = await runTest('http://localhost:9003', messageCount, messageSize, 'socket.io');
    console.log(`Socket.io: ${socketIoTime} ms`);
}

main().catch(console.error);

ws.js

const WebSocket = require('ws');

const wsServer = new WebSocket.Server({ port: 9002 });

wsServer.on('connection', (ws) => {
    console.log('ws: Client connected');

    ws.on('message', (message) => {
        ws.send(message);
    });

    ws.on('close', () => {
        console.log('ws: Client disconnected');
    });
});

console.log('ws server listening on port 9002');

uwebsockets.js

const uWS = require('uWebSockets.js');

uWS.App().ws('/*', {
    open: (ws) => {
        console.log('uWebSockets.js: Client connected');
    },
    message: (ws, message, isBinary) => {
        ws.send(message, isBinary);
    },
    close: (ws, code, message) => {
        console.log('uWebSockets.js: Client disconnected');
    }
}).listen(9001, (token) => {
    if (token) {
        console.log('uWebSockets.js server listening on port 9001');
    } else {
        console.log('Failed to listen to port 9001 with uWebSockets.js');
    }
});

socketio.js

const http = require('http');
const socketIo = require('socket.io');

const server = http.createServer();
const io = socketIo(server);

io.on('connection', (socket) => {
    console.log('Socket.io: Client connected');

    socket.on('message', (message) => {
        socket.send(message);
    });

    socket.on('disconnect', () => {
        console.log('Socket.io: Client disconnected');
    });
});

server.listen(9003, () => {
    console.log('Socket.io server listening on port 9003');
});
e3dio commented 3 months ago

V8 needs some time to warm up, if you move uws.js to last test it will now be the fastest time. Or just test each individually, not in 1 run

You will see ws and uws are same result because you are limited by the slow ws client test. Socket.io is slower tho

uNetworkingAB commented 3 months ago

You are making the most common, classic benchmarking mistake written about here: https://github.com/uNetworking/uWebSockets/tree/master/benchmarks#common-benchmarking-mistakes

TLDR; Do not "benchmark" uWS using a scripted Node.js client - this is benchmarking nothing but your client. Also, you don't track CPU-time so your results are meaningless.