简体   繁体   中英

How can I speed up NodeJS array access?

I wrote a parser in NodeJS that reads a large file of test equipment samples (600MB), de-serializes, and then performs a linear fit of each sample to a table of slopes and offsets (about 10 entries each), eg basically this in a loop:

raw_value = buffer.readUInt16LE(buf_offset)
range = buffer.readUInt16LE(buff_offset+2)
value = raw_value * slope[range] + offset[range]

EDIT: Here's the code. It is proprietary so I had rename everything and change the actual floats, but the idea is the same: a packet comes into the read_packet function hundreds of millions of times. The lookup is the slowest part.

const coeff = {
    mode_x: {
        m: [
            0.0011348513653501,
            0.0011348513653501,
            0.0011348513653501,
            0.0011348513653501,
            0.0003508001973386
        ],
        b: [
            0.0011348513653501,
            0.0011348513653501,
            0.0011348513653501,
            0.0011348513653501,
            0.0003508001973386
        ]
    },
    mode_y: {
        m: [
            0.0000150205642057,
            0.0007774173864163,
            0.0001675113162491,
            0.0000014954827065,
            0.0001675113162491,
            0.0001675113162491,
            0,
            null
        ],
        b: [
            0.0000150205642057,
            0.0007774173864163,
            0.0001675113162491,
            0.0000014954827065,
            0.0001675113162491,
            0.0001675113162491,
            0,
            null
        ]
    }
}

function parse_packet (pkt, length) {
    let accrete = 0
    for (let offset = 0; offset < length; offset += 4) {
        sample = pkt.readUInt16LE(offset)
        xval = pkt.readUInt8(offset + 2)
        yval = pkt.readUInt8(offset + 3)
        x = (i_raw + coeff.mode_x.b[xval]) * coeff.mode_x.b[xval]
        y = (v_raw + coeff.mode_y.m[yval]) * coeff.mode_y.b[yval]
        accrete += x + y
    }
    return accrete
}

I tried moving the m and b arrays out into their own prealloc'd arrays, eg

mode_xm = new Float32Array(50)
coeff.mode_x.m.forEach((x,i) => { mode_xm[i] = x }

But the above made no difference.

If I simply put constants in for slope and offset, the code is ~25 times faster.

Pretty shocked that array/object lookup is so slow compared to C (yes, I know I'm comparing C to JavaScript, bear with my colossal ignorance).

Are there any faster numerical arrays out there? Nothing in npm that I could find. Seems like a plain-old float array with a direct C linkage would be useful.

Thanks, PT

This seems to be a known issue since arrays are objects and the indices are essentially keys in the object code.

Wrong. All engines, including V8 do not use "objects" (meaning: a list of key value pairs) to represent arrays, but use some specialized datastructures depending on the way you use the array.

If I simply put constants in for slope and offset, the code is ~25 times faster.

Right. Constants can be inlined. No calculation is faster than a calculation.

Pretty shocked that array/object lookup is so slow.

How slow? . Thats quite a vague claim.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM