From fd73f2730c7876a2d52d71d88669cc48256da709 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Tue, 12 Apr 2022 19:54:11 -0700 Subject: [PATCH] made ascii string encoding faster (#101777) --- .../standard_message_codec_bench.dart | 15 +++++++++++ .../lib/src/services/message_codecs.dart | 25 ++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/dev/benchmarks/microbenchmarks/lib/foundation/standard_message_codec_bench.dart b/dev/benchmarks/microbenchmarks/lib/foundation/standard_message_codec_bench.dart index 46ce3adbadb..0debebd5f8b 100644 --- a/dev/benchmarks/microbenchmarks/lib/foundation/standard_message_codec_bench.dart +++ b/dev/benchmarks/microbenchmarks/lib/foundation/standard_message_codec_bench.dart @@ -92,5 +92,20 @@ void main() { watch.reset(); + watch.start(); + for (int i = 0; i < _kNumIterations; i += 1) { + codec.encodeMessage('special chars >\u263A\u{1F602}<'); + } + watch.stop(); + + printer.addResult( + description: 'StandardMessageCodec unicode', + value: watch.elapsedMicroseconds.toDouble() / _kNumIterations, + unit: 'us per iteration', + name: 'StandardMessageCodec_unicode', + ); + + watch.reset(); + printer.printToStdout(); } diff --git a/packages/flutter/lib/src/services/message_codecs.dart b/packages/flutter/lib/src/services/message_codecs.dart index 01544872369..d978e0c8754 100644 --- a/packages/flutter/lib/src/services/message_codecs.dart +++ b/packages/flutter/lib/src/services/message_codecs.dart @@ -386,9 +386,28 @@ class StandardMessageCodec implements MessageCodec { } } else if (value is String) { buffer.putUint8(_valueString); - final Uint8List bytes = utf8.encoder.convert(value); - writeSize(buffer, bytes.length); - buffer.putUint8List(bytes); + final Uint8List asciiBytes = Uint8List(value.length); + Uint8List? utf8Bytes; + int utf8Offset = 0; + // Only do utf8 encoding if we encounter non-ascii characters. + for (int i = 0; i < value.length; i += 1) { + final int char = value.codeUnitAt(i); + if (char <= 0x7f) { + asciiBytes[i] = char; + } else { + utf8Bytes = utf8.encoder.convert(value.substring(i)); + utf8Offset = i; + break; + } + } + if (utf8Bytes != null) { + writeSize(buffer, utf8Offset + utf8Bytes.length); + buffer.putUint8List(Uint8List.sublistView(asciiBytes, 0, utf8Offset)); + buffer.putUint8List(utf8Bytes); + } else { + writeSize(buffer, asciiBytes.length); + buffer.putUint8List(asciiBytes); + } } else if (value is Uint8List) { buffer.putUint8(_valueUint8List); writeSize(buffer, value.length);