Improve packed field decoding (#959)
- Inline `_readPacked` manually and `_withLimit` with a pragma to eliminate
closure allocation and calls in packed decoding loops.
- `_readPacked` is manually inlined as VM's inliner doesn't properly fold
constants after the inlinings, see
https://github.com/dart-lang/sdk/issues/60068.
- Introduce `PbList._addUnchecked` to add to the list without checking the
value 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't
return nullable.
- Sprinkle a bunch of `prefer-inline`s to make sure VM will inline one liners.
VM benchmarks before:
```
protobuf_PackedInt32Decoding(RunTimeRaw): 25598.8125 us.
protobuf_PackedInt64Decoding(RunTimeRaw): 67932.43333333333 us.
protobuf_PackedUint32Decoding(RunTimeRaw): 24668.844444444443 us.
protobuf_PackedUint64Decoding(RunTimeRaw): 64615.066666666666 us.
protobuf_PackedSint32Decoding(RunTimeRaw): 26037.275 us.
protobuf_PackedSint64Decoding(RunTimeRaw): 100819.65 us.
protobuf_PackedBoolDecoding(RunTimeRaw): 34733.4 us.
protobuf_PackedEnumDecoding(RunTimeRaw): 48379.659999999996 us.
```
VM benchmarks after:
```
protobuf_PackedInt32Decoding(RunTimeRaw): 19653.9 us.
protobuf_PackedInt64Decoding(RunTimeRaw): 48627.9 us.
protobuf_PackedUint32Decoding(RunTimeRaw): 19279.29090909091 us.
protobuf_PackedUint64Decoding(RunTimeRaw): 50681.8 us.
protobuf_PackedSint32Decoding(RunTimeRaw): 20271.854545454546 us.
protobuf_PackedSint64Decoding(RunTimeRaw): 83777.8 us.
protobuf_PackedBoolDecoding(RunTimeRaw): 24850.555555555555 us.
protobuf_PackedEnumDecoding(RunTimeRaw): 45205.659999999996 us.
```
Wasm benchmarks before (`-O2`):
```
protobuf_PackedInt32Decoding(RunTimeRaw): 64220.0 us.
protobuf_PackedInt64Decoding(RunTimeRaw): 81033.33333333334 us.
protobuf_PackedUint32Decoding(RunTimeRaw): 60800.0 us.
protobuf_PackedUint64Decoding(RunTimeRaw): 82700.0 us.
protobuf_PackedSint32Decoding(RunTimeRaw): 72433.33333333334 us.
protobuf_PackedSint64Decoding(RunTimeRaw): 142150.0 us.
protobuf_PackedBoolDecoding(RunTimeRaw): 27775.0 us.
protobuf_PackedEnumDecoding(RunTimeRaw): 43980.0 us.
```
Wasm benchmarks after:
```
protobuf_PackedInt32Decoding(RunTimeRaw): 56050.0 us.
protobuf_PackedInt64Decoding(RunTimeRaw): 74633.33333333334 us.
protobuf_PackedUint32Decoding(RunTimeRaw): 56525.0 us.
protobuf_PackedUint64Decoding(RunTimeRaw): 69400.0 us.
protobuf_PackedSint32Decoding(RunTimeRaw): 51925.0 us.
protobuf_PackedSint64Decoding(RunTimeRaw): 116250.0 us.
protobuf_PackedBoolDecoding(RunTimeRaw): 18427.272727272728 us.
protobuf_PackedEnumDecoding(RunTimeRaw): 41600.0 us.
```Protocol Buffers (protobuf) are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data.
This repository is home to packages related to protobuf support for Dart.
| Package | Description | Published Version |
|---|---|---|
| protobuf | Runtime library for protocol buffers support. | |
| protoc_plugin | A protobuf protoc compiler plugin used to generate Dart code. | [![pub package] |
| api_benchmark | Benchmarking a number of different api calls. | |
| benchmarks | Benchmarks for various protobuf functions. |
For information about our publishing automation and release process, see https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.