首页 > 解决方案 > 更快地处理 WebSocket 数据

问题描述

所以我从网站的 websocket 获取我的数据(JSON 格式)。它有效,但问题是处理这些数据并不像我希望的那样高效(每一毫秒都很重要)。目前我的处理程序如下所示:

var events_channel = pusher.subscribe('changes');
const eventsQueue = [];

events_channel.bind('channel1', function(data)
{
  eventsQueue.push(data);
  handleNewEvent();
});
events_channel.bind('channel2', function(data)
{
  eventsQueue.push(data);
  handleNewEvent();
});


let processingEvent = false;
function handleNewEvent() 
{
    if(processingEvent){return;}
    processingEvent = true;
    const eventData = eventsQueue.shift();
    if(!eventData){processingEvent = false; return;}

    //Parse the data and do some other stuff with it

    processingEvent = false;
    handleNewEvent();
    return;
}

我对 websocket 在服务器端的工作方式没有发言权,所以我想知道是否有办法节省额外的一两毫秒,或者这基本上是关于我可以在效率方面做些什么。

标签: node.jsperformancewebsocketnetwork-efficiency

解决方案


首先,我认为不需要递归调用“handleNewEvent”,这可能最终会咬你。

这里想到了几件事:

  • 移位数组的性能比仅使用.pop()差得多。
    如果您没有遇到高负载或每秒消息过多的情况,这可能会很好,但可能会搞砸您。考虑编写一个根据您的需求量身定制的自定义队列。

  • 如果您可以假设消息始终具有完全相同的格式,您可以为您的消息编写自定义解析器。只需使用固定偏移量来索引某些部分。这应该优于 JSON.parse,但请注意,您需要绝对确定
    格式永远不会改变。根据我的经验,JSON.parse 花费了大约 2
    微秒,这很难被击败,即使直接索引到缓冲区/字符串也是如此。

  • 尽量不要在你的热路径上分配新对象(预先分配
    你需要的东西),之后不要更改这些对象的字段
    (这将触发新的隐藏类,这会降低
    性能)。

  • 最后,V8 可以优化总是采用相同类型输入的函数。有时最好编写专门的函数来操作不同的类型,而不是使用多态
    函数
    。V8 也将尽可能开始内联。

毕竟,请记住过早优化。编写代码、基准测试、改进缓慢的部分并重复。而且,如果您真的关心性能,那么最好选择一种可以让您更好地控制的语言。在节点中,您最终会在某个时候与 GC 和 V8 对抗。


推荐阅读