-
Notifications
You must be signed in to change notification settings - Fork 187
Improve packed field decoding #959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
It seems in dart2wasm we have
i.e. a regression, is this expected? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with comments
} | ||
break; | ||
case PbFieldType._REPEATED_BYTES: | ||
final list = fs._ensureRepeatedField(meta, fi); | ||
list.add(input.readBytes()); | ||
list._checkModifiable('add'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to be hand-inlined code, omitting the _check
call. It seems not very nice we have to copy&paste this many times.
Why not pass in a bool
whether to check or not, and force inline the function. E.g.
_addInternal(input.readBytes(), omitCheck: true);
@pragma('vm/dart2js/dart2wasm:prefer-inline')
_addInternal(E value, {bool omitCheck = false}) {
_checkModifiable(value, 'add');
if (!omitCheck) _check(value);
_wrappedList.add(value);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function wouldn't work below where we check for modifiable once before adding the elements, and then never check it while adding the elements.
We could have this version:
_addInternal(E value, {bool omitElementCheck = false, bool omitModifiableCheck = false}) {
if (!omitModifiableCheck) _checkModifiable(value, 'add');
if (!omitElementCheck) _check(value);
_wrappedList.add(value);
}
But we would still need a _checkModifiable
call in packed fields as we want to run it once.
Overall not sure if this version is better than the current..
Maybe my CPU became busy with other things while running it, when I run the benchmarks again I consistently get better numbers with this PR. I updated the PR description with more recent benchmark numbers from a run just now. |
I tested this internally in cl/755309114. Merging ... |
Inline
_readPacked
manually and_withLimit
with a pragma to eliminateclosure allocation and calls in packed decoding loops.
_readPacked
is manually inlined as VM's inliner doesn't properly foldconstants after the inlinings, see
Closure and closure context field loads are not folded in AOT dart-lang/sdk#60068.
Introduce
PbList._addUnchecked
to add to the list without checking thevalue for validity and list for mutability.
When decoding a packed field, check the list mutability once, instead of for
every element.
When decoding a packed scalar field, don't check for value validity.
For scalar fields we need to make sure the field value is not null, which is
already guaranteed in the call sites as e.g.
input.readDouble
doesn'treturn nullable.
Sprinkle a bunch of
prefer-inline
s to make sure VM will inline one liners.VM benchmarks before:
VM benchmarks after:
Wasm benchmarks before (
-O2
):Wasm benchmarks after:
cl/755309114