hughfenghen / hughfenghen.github.io

blog
https://hughfenghen.github.io/
44 stars 2 forks source link

Web Worker 传递 ArrayBuffer 时间消耗验证 #108

Open hughfenghen opened 2 years ago

hughfenghen commented 2 years ago

ArrayBuffer 是一个 Transferable_objects,这里验证传递ArrayBuffer的时间消耗

给Worker传递10次ArrayBuffer,单次ArrayBuffer大小 为8Mb

// copy 以下代码可在浏览器控制台执行
const setup = () => {
  self.onmessage = (e) => {
    console.log('time cost:', Date.now() - e.data.t);
  }
}

const createWorker = () => {
  const blob = new Blob([`(${setup.toString()})()`])
  const url = URL.createObjectURL(blob)
  return new Worker(url)
}
const worker = createWorker()

for (let c = 0; c < 10; c += 1) {
  const len = 8 * 1024 * 1024
  const ar = new ArrayBuffer(len)
  const f32 = new Float32Array(ar)
  const randArr = []
  for (let i = 0; i < len / 4; i += 1) {
    randArr.push(Math.random())
  }
  f32.set(randArr)

  setTimeout(function() {
    worker.postMessage({ t: Date.now(), ar }, [ar])
    // 延迟一定时间,避免worker阻塞 影响传输计时
  }, c * 1000);
}

更多相关知识可阅读:JS 多线程并发

hughfenghen commented 2 years ago

执行结果

转移所有权
image

不转移所有权

// 修改为下一行 worker.postMessage({ t: Date.now(), ar }, [ar]) 
worker.postMessage({ t: Date.now(), ar }) 

image

可以得出结论,向worker传递ArrayBuffer成本非常小,可以忽略。 一般情况下postMessage记得带上第二个参数
带上第二个参数[ar],即转移所有权,执行该行代码之后,主线程将无法访问ar。
不带上第二个参数[ar],即会copy数据到worker,后续代码仍然可用,但会消耗CPU和内存。


以上截图是在 2020 M1 Macbook,Chrome 103 上执行的结果。