简体   繁体   English

使用web-sys而不是普通的旧JavaScript是否有性能提升?

[英]Is there a performance gain to use web-sys instead of plain old JavaScript?

I used wasm-bindgen to write a very basic JS/Wasm webapp in which a grayscale transformation (written in Rust) is applied to an image uploaded by the user of the webapp through an <input type="file"> and displayed in a <canvas> . 我使用wasm-bindgen编写一个非常基本的JS / Wasm webapp,其中灰度转换(用Rust编写)应用于webapp用户通过<input type="file">上传的图像并显示在<canvas>

Doing so, I had to load the image in the WebAssembly memory space, apply the transformation on each pixel then return the result in the memory space for the JS to take care of the display: 这样做,我不得不在WebAssembly内存空间中加载图像,对每个像素应用转换,然后将结果返回到内存空间,以便JS负责显示:

import { memory} from "img-grayscale-wasm/img_grayscale_wasm_bg";
import {MyImage} from "img-grayscale-wasm"

//...

async function processImg(file, width, height){
  const canvas = document.getElementById("pixel-grayscale");

  var resp = await fetch(file.name)
  var bytes = await resp.arrayBuffer()

  const myImage = MyImage.new();
  const ptr = myImage.alloc(bytes.byteLength); 

  // Copy to memory space
  const imgArray = new Uint8Array(memory.buffer, ptr, bytes.byteLength);    
  imgArray.set(new Uint8Array(bytes));

  // transform img
  myImage.read_img(ptr, bytes.byteLength) 
  const grayScalePtr = myImage.to_grayscale(width, height)

  // read from memory space
  const arr = new Uint8ClampedArray(memory.buffer, grayScalePtr, width * height * 4);
  let imageData = new ImageData(arr, width);

  getContextFromCanvas(canvas, width, height).putImageData(imageData, 0, 0);
}

I think I can avoid the whole process of copying stuff back and forth to the memory space if I use the web's API binding defined in the web-sys crate, from fetch ing the file to the display of the grayscaled picture. 如果我使用web-sys crate中定义的web的API绑定,从fetch文件到灰度图片的显示,我想我可以避免将内容来回复制到内存空间的整个过程。

This is where I get confused: performance-wise, is there a gain in using web-sys and its web's API bindings instead of doing it all in JavaScript? 这是我感到困惑的地方:性能方面,是否有使用web-sys及其网络API绑定而不是在JavaScript中完成所有工作? Well, I suppose there is, but where is it? 好吧,我想有,但它在哪里?

If I understand you correctly, you're marshalling the data back and forth using browser methods at the moment to bask in web-sys 's glory. 如果我理解正确的话,你现在使用浏览器方法来回调整数据,以充实web-sys的荣耀。 I have some good news and some bad news for you. 我有一些好消息和一些坏消息。

The good news is that if your code is laid out the way you've said it is (and this is where a snippet would've come in very handy), you'll gain on one memory copy going each way. 好消息是,如果您的代码按照您所说的方式布局(并且这是一个非常方便的代码段),您将获得每个方向的一个内存副本。

Right now, the process would be as follows: 目前,流程如下:

            1              2
         ======>        =====>       \
Browser         WebWorker      Rust   ||
         <======        <=====      <=/
            4              3

(Quality ASCII art, I know) (质量ASCII艺术,我知道)

1 is a user input of some sort. 1是某种用户输入。 2->3 is a fetch cycle. 2-> 3是fetch周期。 4 is the marshalling back. 4是编组回来。

At best, if your code is indeed structured this way, you can get rid of the data copy on steps 2 and 3 by moving everything to web-sys . 在最好的情况,如果你的代码确实这种方式构造,您可以通过移动一切摆脱的数据副本的步骤2和3 web-sys You will not get rid of the (relatively minimal) copy of data on 1, nor on 4. 你不会在1和4上摆脱(相对最小的)数据副本。

Depending on the size of the image you're desaturating, and the computer you're running it on, this may or may not present a gain in performance. 根据您正饱和的图像大小以及运行它的计算机,这可能会也可能不会带来性能提升。 I have not looked into the internals of web-sys (this isn't typically my area of expertise - I'm an embedded systems developer), so I cannot speak about the internals of the crate itself, but I assume fetch() as done by the browser or done through web-sys to be identical in performance. 我没有看过web-sys的内部(这通常不是我的专业领域 - 我是一个嵌入式系统开发人员),所以我不能谈论crate本身的内部,但我假设fetch()为由浏览器完成或通过web-sys完成,性能相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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