Async Promise未提升执行速度,请求排查并行化代码问题
并行化点云处理无性能提升问题排查
我尝试通过并行化每个数据块来提升处理速度,但执行速度并未得到提升,恳请帮忙找出问题所在。
主循环代码
for (let m = 0; m < keyCountMap.length; m += 2) { fetchWorker.postMessage([nodePages, keyCountMap]); // console.log(m, keyCountMap[m], keyCountMap.length); let myRoot = nodePages[keyCountMap[m]]; const view = await Copc.loadPointDataView(filename, copc, myRoot); let getters = ["X", "Y", "Z", "Intensity"].map(view.getter); let chunkCount = 2; let totalCalled = 0; for (let j = 0; j < keyCountMap[m + 1]; j += chunkCount) { let remaining = keyCountMap[m + 1] - totalCalled; let localChunkCount = Math.min(chunkCount, remaining); totalCalled += localChunkCount; const pointTemp = new Array(localChunkCount).fill(null); const promises = pointTemp.map((element, index) => readPoints(index + j, getters) ); const done = await Promise.all(promises); } }
readPoints及相关代码
const readPoints = (id, getters) => { return new Promise((resolve, reject) => { let returnPoint = getXyzi(id, getters); positions.push( returnPoint[0] - x_min - 0.5 * width, returnPoint[1] - y_min - 0.5 * width, returnPoint[2] - z_min - 0.5 * width ); const vx = (returnPoint[3] / 65535) * 255; color.setRGB(vx, vx, vx); colors.push(color.r, color.g, color.b); return resolve(true); }); }; function getXyzi(index, getters) { return getters.map((get) => get(index)); }
Worker代码情况
从截图来看,Worker仅监听了message事件接收nodePages和keyCountMap数据,但未实现任何实际的点数据处理逻辑,代码大致如下:
self.onmessage = function(e) { const [nodePages, keyCountMap] = e.data; // 无后续处理逻辑 };
问题根源分析
- 伪并行Promise:
readPoints里的Promise只是套了异步壳子,所有计算逻辑都是同步执行的,Promise.all等待的任务仍在主线程串行跑,完全没起到并行分流作用。 - Worker未被有效利用:主线程给Worker发了消息,但Worker没有处理点数据的逻辑,等于白开了Worker,没分担任何计算压力。
- Chunk粒度太小:
chunkCount = 2每次只处理2个点,Promise调度的开销甚至会超过并行带来的收益,反而拖慢速度。 - 串行加载阻塞主线程:外层
await Copc.loadPointDataView是串行执行的,加载完一个视图才处理下一个,这部分也没并行起来。
优化建议
- 把点处理逻辑移到Worker:将坐标转换、颜色计算等逻辑放到Worker中,让Worker负责计算,处理完后把结果片段(如
positions、colors的子数组)发回主线程。 - 实现真正的异步并行:主线程负责加载数据视图,然后将getters和点索引范围发给Worker,让Worker在后台并行处理,避免阻塞主线程。
- 增大Chunk粒度:将
chunkCount调整为几百或几千,减少线程间通信的开销。 - 并行加载数据视图:如果多个
Copc.loadPointDataView调用无依赖,用Promise.all并行加载多个视图,提升整体效率。
内容的提问来源于stack exchange,提问作者Pravin Poudel
相关产品推荐
相关产品推荐

