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.
```
10 files changed
tree: 55badecc88b49c236b3fd87ddebb00e662d578c3
  1. .github/
  2. api_benchmark/
  3. benchmarks/
  4. protobuf/
  5. protoc_plugin/
  6. tool/
  7. .gitignore
  8. analysis_options.yaml
  9. AUTHORS
  10. LICENSE
  11. mono_repo.yaml
  12. README.md
README.md

Protobuf support for Dart

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.

PackageDescriptionPublished Version
protobufRuntime library for protocol buffers support.pub package
protoc_pluginA protobuf protoc compiler plugin used to generate Dart code.[![pub package]
api_benchmarkBenchmarking a number of different api calls.
benchmarksBenchmarks for various protobuf functions.

Publishing automation

For information about our publishing automation and release process, see https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.