From f279fe81faada11f531a2d88b1b50bb4990deeca Mon Sep 17 00:00:00 2001 From: zengdongbao Date: Tue, 4 Jan 2022 16:41:32 +0800 Subject: optimized wire.js inbound function, reduce combine times If the frame data is large, it will be divided into multiple packets. In the current processing mode, each packet will be merged with the old packet into a new buffer, resulting in a large number of redundant operations. Optimization scheme: Use array cache packets, and finally use DataView.set to do a merge. After testing, 1080p picture data merging time can be reduced from 100ms to <5ms Signed-off-by: zengdongbao --- src/wire.js | 55 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/wire.js b/src/wire.js index 6a6d51d..0d5c943 100644 --- a/src/wire.js +++ b/src/wire.js @@ -33,6 +33,7 @@ function SpiceWireReader(sc, callback) this.sc = sc; this.callback = callback; this.needed = 0; + this.size = 0; this.buffers = []; @@ -55,6 +56,7 @@ SpiceWireReader.prototype = if (this.needed == 0) { this.buffers.push(mb); + this.size += mb.byteLength; return; } @@ -64,6 +66,7 @@ SpiceWireReader.prototype = { if (mb.byteLength > this.needed) { + this.size = mb.byteLength - this.needed; this.buffers.push(mb.slice(this.needed)); mb = mb.slice(0, this.needed); } @@ -73,32 +76,40 @@ SpiceWireReader.prototype = else { this.buffers.push(mb); + this.size += mb.byteLength; } - /* If we have fragments that add up to what we need, combine them */ - /* FIXME - it would be faster to revise the processing code to handle - ** multiple fragments directly. Essentially, we should be - ** able to do this without any slice() or combine_array_buffers() calls */ - while (this.buffers.length > 1 && this.buffers[0].byteLength < this.needed) - { - var mb1 = this.buffers.shift(); - var mb2 = this.buffers.shift(); - - this.buffers.unshift(combine_array_buffers(mb1, mb2)); - } - - - while (this.buffers.length > 0 && this.buffers[0].byteLength >= this.needed) - { - mb = this.buffers.shift(); - if (mb.byteLength > this.needed) - { - this.buffers.unshift(mb.slice(this.needed)); - mb = mb.slice(0, this.needed); + /* Optimization - All it takes is one combine */ + while (this.size >= this.needed) { + var count = 0; + var frame = new ArrayBuffer(this.needed); + var view = new Uint8Array(frame); + + while (count < frame.byteLength && this.buffers.length > 0) { + var buf = this.buffers.shift(); + if (!buf) { + return; + } + var uint8 = new Uint8Array(buf); + var step = frame.byteLength - count; + + /* Optimization - use dataview.set() instead of combine_array_buffers() */ + if (uint8.length <= step) { + view.set(uint8, count); + count += uint8.length; + this.size -= uint8.length; + } else { + var temp = uint8.slice(0, step); + view.set(temp, count); + count += temp.length; + this.size -= temp.length; + + this.buffers.unshift(uint8.slice(step)); + } } - this.callback.call(this.sc, mb, - this.saved_msg_header || undefined); + + this.callback.call(this.sc, frame, this.saved_msg_header || undefined); } }, -- cgit v1.2.3