Javascript 循环缓冲队列实现 "FIFO queue"

Javascript circular buffer queue implementation as a "FIFO queue"

数组有循环缓冲版本吗?假设一次最大推送元素的数量是已知的,我是否必须派生自己的 FIFO 队列以提高性能?

这是我尝试过的:

循环实现:

function CBuf(n)
{
    var ctrPush=0;
    var ctrPop=0;
    var ab = new ArrayBuffer(n*4);
    var buf = new Uint32Array(ab);

    this.push = function (v) {
        buf[ctrPush%n] = v;
        ctrPush++;
    };


    this.empty = function () {
         return (ctrPush == ctrPop);
    }


    this.pop = function () {
        var tmp = buf[ctrPop%n];
        ctrPop++;
        return tmp;
    };
}

基准简单数组:

{
    var t1 = new Date();
    var arr = [];

    for (var j = 0; j < 1000; j++) {
        for (var i = 0; i < 10000; i++) {
            arr.push(i); 
        }
        for (var i = 0; i < 10000; i++) {
            arr.shift();
        }
    }
    var t2 = new Date();

    console.log("array time=" + (t2 - t1));
}

基准循环缓冲区:

{
    var t1 = new Date();
    var arr = new CBuf(10000);

    for (var j = 0; j < 1000; j++) {
        for (var i = 0; i < 10000; i++) {
            arr.push(i);
        }
        for (var i = 0; i < 10000; i++) {
            if(!arr.empty())
                arr.pop();
        }
    }
    var t2 = new Date();

    console.log("cbuf time="+(t2 - t1));
}

结果:

array time=2749 ms
cbuf time=552 ms (230 if using &(n-1) instead of %n)

最多 70k 个元素:

array time=19456 ms
cbuf time=3872 ms (1700 if using &(n-1) instead of %n)

它们似乎具有相似的时间复杂度,但数组移位在 Nodejs 中较慢。也许它会检查很多事情,比如边界检查和不断调整大小?我需要类似 SIMD 变量但长度为 n 的东西。

我计划在 nodejs 服务器间工作调度程序队列上使用它。

编辑:

这里可以测试:

https://jsperf.com/fifo-array-vs-circular-buffer-preallocated

按下和移动很慢。只需使用数组索引。