Performance of the fill operation in _wasm_ versus JS - Sable/matmachjs GitHub Wiki

Performance of fill() using JS versus wasm

In the MatMachJS library, the fill() library call takes an array parameter and a value and fills this array with that particular value. This can be done in two ways: either we use a wasm implementation, or (2) we use the TypedArray view of the data, and its associated fill() version. Let's look at both implementations:

   (export "fill" (func $fill))
    (func $fill (param $arr_ptr i32)(param $val f64)(result i32)
        (local $len i32)(local $step i32)
        (set_local $len (i32.shl (i32.load offset=4 align=4 (get_local $arr_ptr))(i32.const 3)))
        (set_local $arr_ptr (i32.load offset=8 align=4 (get_local $arr_ptr)))
        (if (i32.lt_s (get_local $step)(get_local $len))
            (then
            (set_local $len (i32.add (get_local $len)(get_local $arr_ptr)))
            (set_local $step (get_local $arr_ptr))
            loop
                (f64.store offset=0 align=8 (get_local $step)(get_local $val))
                (set_local $step (i32.add (get_local $step)(i32.const 8)))  
                (br_if 0 (i32.lt_s (get_local $step)(get_local $len)))
            end))
        get_local $arr_ptr
    )

In JS:

 function fill(array/*:MachArray*/,value /*:number*/) {
       array._data.fill(value);
}

Experiment

We have ran the fill() functions against two inputs:

  • large, a 5000x5000 square matrix.
  • medium, a 1000x1000 square matrix.

To run the experiments we have executed the benchmarks under both steady-state time and start-up time for a total of 30 iterations in each specific configuration.

The following table presents the times for this experiment:

state implementation input-size time(s)
steady wasm large 0.224(0.03)
steady JS large 0.224(0.02)
warm-up wasm large 0.224(0.02)
warm-up JS large 0.224(0.03)
steady wasm medium 0.0038(0.001)
steady JS medium 0.0039(0.0004)
warm-up wasm medium 0.0039(0.001)
warm-up JS medium 0.0038(0.0004)

Results

No difference between either approach. Since a wasm implementation is necessary for compiler back-end support, the library will used this internally.