Skip to content

Typed data array operations are slow, read/write one byte at a time #52710

Closed
@osa1

Description

@osa1
Optimized code for `_Float64List.[]`
 (func $_Float64List.\5b\5d (type $type$63) (param $0 (ref $type$17)) (param $1 i64) (result (ref null $type$56))
  (local $2 (ref $type$4))
  (local $3 (ref $type$66))
  (local $4 (ref $type$65))
  (local $5 i32)
  (local.set $3
   (ref.cast $type$66
    (local.get $0)))
  (block $label$1
   (if
    (i64.ge_s
     (local.get $1)
     (i64.const 0))
    (br_if $label$1
     (i64.gt_s
      (call $_TypedListBase.length
       (local.get $3))
      (local.get $1))))
   (struct.set $type$65 0
    (local.tee $4
     (struct.new_default $type$65))
    (i32.const 271))
   (call $IndexError.withLength
    (local.get $4)
    (local.get $1)
    (call $_TypedListBase.length
     (local.get $3))
    (global.get $global$54))
   (call $Error._throw
    (local.get $4)
    (call $StackTrace.current))
   (unreachable))
  (struct.new $type$9
   (i32.const 11)
   (f64.reinterpret_i64
    (i64.or
     (i64.or
      (i64.or
       (i64.or
        (i64.or
         (i64.or
          (i64.or
           (i64.extend_i32_u
            (array.get_u $type$4
             (local.tee $2
              (struct.get $type$66 3
               (local.get $3)))
             (local.tee $5
              (i32.wrap_i64
               (i64.shl
                (local.get $1)
                (i64.const 3))))))
           (i64.shl
            (i64.extend_i32_u
             (array.get_u $type$4
              (local.get $2)
              (i32.add
               (local.get $5)
               (i32.const 1))))
            (i64.const 8)))
          (i64.shl
           (i64.extend_i32_u
            (array.get_u $type$4
             (local.get $2)
             (i32.add
              (local.get $5)
              (i32.const 2))))
           (i64.const 16)))
         (i64.shl
          (i64.extend_i32_u
           (array.get_u $type$4
            (local.get $2)
            (i32.add
             (local.get $5)
             (i32.const 3))))
          (i64.const 24)))
        (i64.shl
         (i64.extend_i32_u
          (array.get_u $type$4
           (local.get $2)
           (i32.add
            (local.get $5)
            (i32.const 4))))
         (i64.const 32)))
       (i64.shl
        (i64.extend_i32_u
         (array.get_u $type$4
          (local.get $2)
          (i32.add
           (local.get $5)
           (i32.const 5))))
        (i64.const 40)))
      (i64.shl
       (i64.extend_i32_u
        (array.get_u $type$4
         (local.get $2)
         (i32.add
          (local.get $5)
          (i32.const 6))))
       (i64.const 48)))
     (i64.shl
      (i64.extend_i32_u
       (array.get_u $type$4
        (local.get $2)
        (i32.add
         (local.get $5)
         (i32.const 7))))
      (i64.const 56))))))

Currently typed data lists use a i8 array as the buffer and read/write one byte at a time. I can't tell from the code why we use a byte array in typed data lists, but I suspect it has to do with JS interop or getting different views of a lists without copying (which would break sharing).

Opening this issue to document the requirements and alternatives.

It's a bit difficult to find where the typed list constructors and accessors are generated, so here are a few links:

Metadata

Metadata

Assignees

Labels

area-dart2wasmIssues for the dart2wasm compiler.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions