-
Notifications
You must be signed in to change notification settings - Fork 197
Open
Description
I don't think this can be fixed, but it's still worth documenting this issue somewhere probably..
PbList.add currently checks the element type, and then calls GrowableList.add, which checks the element type again.
Here's the relevant Wasm when compiled with -O2: (the default optimization setting when building Flutter apps)
(func $PbList.add (;353;) (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
(local $var2 (ref $PbList))
(local $var3 (ref $_Type))
(local $var4 (ref $#Closure-0-1))
local.get $var0
ref.cast $PbList
local.tee $var2
struct.get $PbList $field2
local.set $var3
local.get $var1
ref.is_null
if (result i32)
local.get $var3
struct.get $_Type $field2
else
local.get $var3
local.get $var1
ref.as_non_null
call $_InterfaceType._checkInstance
end
...
)
(func $GrowableList.add (;174;) (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
(local $var2 (ref $_Type))
(local $var3 (ref $WasmListBase))
(local $var4 (ref $#Top))
(local $var5 i64)
(local $var6 i32)
local.get $var0
ref.cast $WasmListBase
local.tee $var3
struct.get $WasmListBase $field2
local.set $var2
local.get $var1
ref.is_null
if (result i32)
local.get $var2
struct.get $_Type $field2
else
block $label0 (result i32)
i32.const 1
local.get $var2
struct.get $_Type $field0
local.tee $var6
i32.const 8
i32.eq
br_if $label0
drop
local.get $var1
ref.as_non_null
local.set $var4
local.get $var6
i32.const 12
i32.eq
if
local.get $var2
local.get $var4
call $_InterfaceType._checkInstance
br $label0
end
local.get $var2
local.get $var4
local.get $var2
struct.get $_Type $field0
i32.const 287
i32.add
call_indirect (param (ref $_Type) (ref $#Top)) (result i32)
end $label0
end
i32.eqz
if
local.get $var1
local.get $var2
call $_TypeError._throwAsCheckError
end
...
)Now consider a packed field decoding loop, with #959.
For each 4-byte integer, we box the integer, and then check the type of it twice.
To have an idea of how much we could save, if I omit type checks in the generated code with -O4, here's before and after:
// Before
protobuf_PackedInt32Decoding(RunTimeRaw): 49775.0 us.
// After
protobuf_PackedInt32Decoding(RunTimeRaw): 36812.5 us.
That's 26% of decoding time wasted on redundant type checks.
Metadata
Metadata
Assignees
Labels
No labels