I've been spending my day trying to optimize my Socket.io app, when I came across a rather interesting chunk of code in Socket.io-Adapter, index.js. The way the broadcast function works was the code which SIGNIFICANTLY decreased the speed of my app. The functional part which does the broadcasting is this chunk:
for (var id in room) {
if (ids[id] || ~except.indexOf(id)) continue;
socket = self.nsp.connected[id];
if (socket) {
socket.packet(encodedPackets, true, flags.volatile);
ids[id] = true;
}
}
A for in loop seemed in this case to be almost retarded, no offence to anyone, since broadcasting in most scenarios need to be quick. So I simply switched it out to Object.keys with a forEach loop like this:
Object.keys(room).forEach(function (id) {
if (ids[id] || ~except.indexOf(id)) {
socket = self.nsp.connected[id];
if (socket) {
socket.packet(encodedPackets, true, flags.volatile);
ids[id] = true;
}
}
}
And I got a major performance increase. In my tests I ran a client-sim against my app starting with 50 users sending a message each second to the server and timing how long it took for the message to return to the origin socket. With the for in loop I got an average of 67ms. With Object.keys().forEach it dropped to 24ms.
I can't figure out why it is like this, why someone chose the loop in this case. So I seek some kind of explanation here, why is for in used?
I've tried twittering Guillermo Rauch, but I'm waiting for a response.