Skip to content

Commit

Permalink
Avoid adding empty splices in CodedBufferWriter (#886)
Browse files Browse the repository at this point in the history
By avoiding allocating empty `Uint8List`s this saves a few percent in dart2js
-O4 in the benchmark reported in #885.

|                              | Before     | After      | Diff                |
|------------------------------|------------|------------|---------------------|
| AOT                          | 122,917 us | 122,741 us |                     |
| JIT                          |  93,376 us |  94,880 us |                     |
| dart2js -O4                  | 271,111 us | 258,250 us | -12,861 us, -4.7%   |
| dart2wasm --omit-type-checks | 196,454 us | 195,300 us |                     |

Number of splices in the benchmark before this change: 21,123
After: 20,857
  • Loading branch information
osa1 authored Oct 26, 2023
1 parent 23dffde commit 9a73936
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions protobuf/lib/src/protobuf/coded_buffer_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,11 @@ class CodedBufferWriter {
/// Add a [Uint8List] splice, without copying. These bytes will be directly
/// copied into the output buffer by [writeTo].
void writeRawBytes(Uint8List value) {
final length = value.lengthInBytes;
if (length == 0) return;
_commitSplice();
_splices.add(value);
_bytesTotal += value.lengthInBytes;
_bytesTotal += length;
}

/// Start writing a length-delimited data.
Expand Down Expand Up @@ -340,11 +342,22 @@ class CodedBufferWriter {
_writeVarint32(value ? 1 : 0);
break;
case PbFieldType._BYTES_BIT:
_writeBytesNoTag(
value is Uint8List ? value : Uint8List.fromList(value));
final List<int> bytes = value;
if (bytes is Uint8List) {
_writeBytesNoTag(bytes);
} else if (bytes.isEmpty) {
_writeEmptyBytes();
} else {
_writeBytesNoTag(Uint8List.fromList(bytes));
}
break;
case PbFieldType._STRING_BIT:
_writeBytesNoTag(const Utf8Encoder().convert(value));
final String string = value;
if (string.isEmpty) {
_writeEmptyBytes();
} else {
_writeBytesNoTag(const Utf8Encoder().convert(string));
}
break;
case PbFieldType._DOUBLE_BIT:
_writeDouble(value);
Expand Down Expand Up @@ -405,6 +418,10 @@ class CodedBufferWriter {
writeRawBytes(value);
}

void _writeEmptyBytes() {
writeInt32NoTag(0);
}

void _writeTag(int fieldNumber, int wireFormat) {
writeInt32NoTag(makeTag(fieldNumber, wireFormat));
}
Expand Down

0 comments on commit 9a73936

Please sign in to comment.