简体   繁体   中英

How to measure performance with async functions in javascript

I've created a small app that compares the speeds of WebAssembly and Javascript. To my surprise, JavaScript is way faster at calculating factorials of a large number. Or at least it seems like it is. I am pretty sure this is not right and is caused by the await syntax I'm using. (The functions are the same.) Also, what are some really time heavy tasks I can use to compare those two? This doesn't really seem that time consuming, since it takes less than a 0.1 millisecond.

AssemblyScript (this gets compiled into wasm)

// The entry file of your WebAssembly module.
export function fib(num: i32): i32 {
  var a: i32 = 1,
    b: i32 = 0,
    temp: i32;

  while (num > 0) {
    temp = a;
    a = a + b;
    b = temp;
    num--;
  }

  return b;
}

App.js

import waApi from "./api";
...
  <button
       onClick={async () => {
       const t0 = performance.now();
       (await waApi).fib(200);
       const t1 = performance.now();
       this.updateGraph(t1 - t0, "wa");
       const t2 = performance.now();
       this.fib(200);
       const t3 = performance.now();
       this.updateGraph(t3 - t2, "js");
       }}>
Calculate with both 
  </button>

api.js

import { instantiateStreaming } from "assemblyscript/lib/loader";

export default instantiateStreaming(fetch("./assembly.wasm"));

The problem with micro-benchmarks (ie benchmarks that analyse the performance of small, very fast function) is that you almost always end up measuring the wrong thing. Your measurements are going to be heavily skewed by:

  • The overhead involved in invoking WebAssembly functions from JavaScript
  • The ability of the AssemblyScript compiler (which is very new) to optimise your function
  • The accuracy of your timer
  • The time for your JavaScript engine to reach peak optimisation

Just to name a few!

A more realistic benchmark would perform calculations that execute a far greater range of WebAssembly operations, be more 'realistic' in nature (ie measure the types of load you really would offload to WebAssembly), and take longer to execute.

Here's a much better benchmark based on a GameBoy emulator:

https://medium.com/@torch2424/webassembly-is-fast-a-real-world-benchmark-of-webassembly-vs-es6-d85a23f8e193

It should be

import waApi from "./api";

class Test extends React.Component { 
  async componentDidMount() {
    this.wasmModule = await waApi;
  }

  render() {
    return (
      <button
        onClick={() => {
          const module = this.wasmModule;
          if (!module) {
            console.warn("module not yet loaded. Try later");
            return;
          }
          const t0 = performance.now();
          module.fib(200);
          const t1 = performance.now();
          this.updateGraph(t1 - t0, "wa");
          const t2 = performance.now();
          this.fib(200);
          const t3 = performance.now();
          this.updateGraph(t3 - t2, "js");
        }}>
    );
  }
}

Because in your example for wasm part you also measured loading and instantiation of module.

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