[vm_service] Decode incoming JSON in one step instead of two
Currently we decode incoming data as a string, then parse the string as
JSON.
We can do it in one step by fusing a `Utf8Decoder` with a `JsonDecoder`,
which will be faster.
A difference between `jsonDecode` and the fused version is that
`jsonDecode` returns `dynamic`, the fused version returns `Object?`.
To keep changes as small as possible we cast the return value of the
fused verison to `dynamic` in this CL.
However using `dynamic` values is often slower than type casting it to
the right type and then using it. So it might make sense to cast it to
something like `Map<String, dynamic>` in a separate CL.
Change-Id: I76de535a72ae5532db5a27e543929519c48c701c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371080
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index c227706..31fe1af 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -12,7 +12,8 @@
// ignore_for_file: overridden_fields
import 'dart:async';
-import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
+import 'dart:convert'
+ show base64, jsonDecode, JsonDecoder, jsonEncode, utf8, Utf8Decoder;
import 'dart:typed_data';
export 'snapshot_graph.dart'
@@ -1825,11 +1826,11 @@
final int dataOffset = bytes.getUint32(0, Endian.little);
final metaLength = dataOffset - metaOffset;
final dataLength = bytes.lengthInBytes - dataOffset;
- final meta = utf8.decode(Uint8List.view(
- bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength));
+ final decoder = (const Utf8Decoder()).fuse(const JsonDecoder());
+ final map = decoder.convert(Uint8List.view(
+ bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength)) as dynamic;
final data = ByteData.view(
bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
- final map = jsonDecode(meta)!;
if (map['method'] == 'streamNotify') {
final streamId = map['params']['streamId'];
final event = map['params']['event'];
diff --git a/pkg/vm_service/tool/dart/generate_dart_client.dart b/pkg/vm_service/tool/dart/generate_dart_client.dart
index cf55d82..986630d 100644
--- a/pkg/vm_service/tool/dart/generate_dart_client.dart
+++ b/pkg/vm_service/tool/dart/generate_dart_client.dart
@@ -20,7 +20,8 @@
// ignore_for_file: overridden_fields
import 'dart:async';
-import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
+import 'dart:convert'
+ show base64, jsonDecode, JsonDecoder, jsonEncode, utf8, Utf8Decoder;
import 'dart:typed_data';
export 'snapshot_graph.dart' show HeapSnapshotClass,
@@ -148,11 +149,11 @@
final int dataOffset = bytes.getUint32(0, Endian.little);
final metaLength = dataOffset - metaOffset;
final dataLength = bytes.lengthInBytes - dataOffset;
- final meta = utf8.decode(Uint8List.view(
- bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength));
+ final decoder = (const Utf8Decoder()).fuse(const JsonDecoder());
+ final map = decoder.convert(Uint8List.view(
+ bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength)) as dynamic;
final data = ByteData.view(
bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
- final map = jsonDecode(meta)!;
if (map['method'] == 'streamNotify') {
final streamId = map['params']['streamId'];
final event = map['params']['event'];