Skip to content

Commit 3a9da96

Browse files
authored
Minor cleanup to CPU profile screen code (#9324)
1 parent 6e30b40 commit 3a9da96

File tree

3 files changed

+80
-95
lines changed

3 files changed

+80
-95
lines changed

packages/devtools_app/lib/src/screens/profiler/cpu_profile_model.dart

Lines changed: 73 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ class CpuProfilePair {
153153
required String processId,
154154
}) async {
155155
await transformer.processData(functionProfile, processId: processId);
156-
if (codeProfile != null) {
157-
await transformer.processData(codeProfile!, processId: processId);
156+
if (codeProfile case final codeProfile?) {
157+
await transformer.processData(codeProfile, processId: processId);
158158
}
159159
}
160160
}
@@ -166,11 +166,13 @@ class CpuProfileData with Serializable {
166166
required this.cpuSamples,
167167
required this.profileMetaData,
168168
required this.rootedAtTags,
169-
}) {
170-
_cpuProfileRoot = CpuStackFrame.root(profileMetaData);
171-
}
169+
}) : cpuProfileRoot = CpuStackFrame.root(profileMetaData);
172170

173171
factory CpuProfileData.fromJson(Map<String, Object?> json_) {
172+
if (json_.isEmpty) {
173+
return CpuProfileData.empty();
174+
}
175+
174176
final json = _CpuProfileDataJson(json_);
175177

176178
// All CPU samples.
@@ -187,15 +189,17 @@ class CpuProfileData with Serializable {
187189
final samplePeriod =
188190
observedSamplePeriod(samples) ?? json.samplePeriod ?? 0;
189191

192+
final timeOriginMicros = json.timeOriginMicros;
193+
final timeExtentMicros = json.timeExtentMicros;
190194
final profileMetaData = CpuProfileMetaData(
191195
sampleCount: json.sampleCount ?? 0,
192196
samplePeriod: samplePeriod,
193197
stackDepth: json.stackDepth ?? 0,
194-
time: (json.timeOriginMicros != null && json.timeExtentMicros != null)
198+
time: (timeOriginMicros != null && timeExtentMicros != null)
195199
? (TimeRange()
196-
..start = Duration(microseconds: json.timeOriginMicros!)
200+
..start = Duration(microseconds: timeOriginMicros)
197201
..end = Duration(
198-
microseconds: json.timeOriginMicros! + json.timeExtentMicros!,
202+
microseconds: timeOriginMicros + timeExtentMicros,
199203
))
200204
: null,
201205
);
@@ -329,10 +333,10 @@ class CpuProfileData with Serializable {
329333
});
330334

331335
for (final sample in tagProfile.cpuSamples) {
332-
String? updatedId = idMapping[sample.leafId];
336+
String? updatedId = idMapping[sample.leafId]!;
333337
samples.add(
334338
CpuSampleEvent(
335-
leafId: updatedId!,
339+
leafId: updatedId,
336340
userTag: sample.userTag,
337341
vmTag: sample.vmTag,
338342
traceJson: sample.toJson,
@@ -540,7 +544,17 @@ class CpuProfileData with Serializable {
540544
);
541545
}
542546

543-
factory CpuProfileData.empty() => CpuProfileData.fromJson({});
547+
factory CpuProfileData.empty() => CpuProfileData._(
548+
stackFrames: {},
549+
cpuSamples: [],
550+
profileMetaData: CpuProfileMetaData(
551+
sampleCount: 0,
552+
samplePeriod: 0,
553+
stackDepth: 0,
554+
time: null,
555+
),
556+
rootedAtTags: false,
557+
);
544558

545559
/// Generates [CpuProfileData] from the provided [cpuSamples].
546560
///
@@ -556,45 +570,48 @@ class CpuProfileData with Serializable {
556570
// of all stacks, regardless of entrypoint. This should never be seen in the
557571
// final output from this method.
558572
const kRootId = 0;
559-
final traceObject = <String, Object?>{
560-
CpuProfileData._sampleCountKey: cpuSamples.sampleCount,
561-
CpuProfileData._samplePeriodKey: cpuSamples.samplePeriod,
562-
CpuProfileData._stackDepthKey: cpuSamples.maxStackDepth,
563-
CpuProfileData._timeOriginKey: cpuSamples.timeOriginMicros,
564-
CpuProfileData._timeExtentKey: cpuSamples.timeExtentMicros,
565-
CpuProfileData._stackFramesKey: cpuSamples.generateStackFramesJson(
566-
isolateId: isolateId,
567-
// We want to ensure that if [kRootId] ever changes, this change is
568-
// propagated to [cpuSamples.generateStackFramesJson].
569-
// ignore: avoid_redundant_argument_values
570-
kRootId: kRootId,
571-
buildCodeTree: buildCodeTree,
572-
),
573-
CpuProfileData._traceEventsKey: [],
574-
};
573+
574+
// Generate the stack frames first as it builds and tracks
575+
// the timeline tree for each sample.
576+
final stackFrames = cpuSamples.generateStackFramesJson(
577+
isolateId: isolateId,
578+
// We want to ensure that if [kRootId] ever changes, this change is
579+
// propagated to [cpuSamples.generateStackFramesJson].
580+
// ignore: avoid_redundant_argument_values
581+
kRootId: kRootId,
582+
buildCodeTree: buildCodeTree,
583+
);
575584

576585
// Build the trace events.
586+
final traceEvents = <Map<String, Object?>>[];
577587
for (final sample in cpuSamples.samples ?? <vm_service.CpuSample>[]) {
578588
final tree = _CpuProfileTimelineTree.getTreeFromSample(sample)!;
579589
// Skip the root.
580590
if (tree.frameId == kRootId) {
581591
continue;
582592
}
583-
(traceObject[CpuProfileData._traceEventsKey]! as List<Object?>).add({
593+
traceEvents.add({
584594
'ph': 'P', // kind = sample event
585595
'name': '', // Blank to keep about:tracing happy
586596
'pid': cpuSamples.pid,
587597
'tid': sample.tid,
588598
'ts': sample.timestamp,
589599
'cat': 'Dart',
590600
CpuProfileData.stackFrameIdKey: '$isolateId-${tree.frameId}',
591-
'args': {
592-
if (sample.userTag != null) userTagKey: sample.userTag,
593-
if (sample.vmTag != null) vmTagKey: sample.vmTag,
594-
},
601+
'args': {userTagKey: ?sample.userTag, vmTagKey: ?sample.vmTag},
595602
});
596603
}
597604

605+
final traceObject = <String, Object?>{
606+
CpuProfileData._sampleCountKey: cpuSamples.sampleCount,
607+
CpuProfileData._samplePeriodKey: cpuSamples.samplePeriod,
608+
CpuProfileData._stackDepthKey: cpuSamples.maxStackDepth,
609+
CpuProfileData._timeOriginKey: cpuSamples.timeOriginMicros,
610+
CpuProfileData._timeExtentKey: cpuSamples.timeExtentMicros,
611+
CpuProfileData._stackFramesKey: stackFrames,
612+
CpuProfileData._traceEventsKey: traceEvents,
613+
};
614+
598615
await _addPackageUrisToTraceObject(isolateId, traceObject);
599616

600617
return CpuProfileData.fromJson(traceObject);
@@ -674,6 +691,8 @@ class CpuProfileData with Serializable {
674691

675692
final CpuProfileMetaData profileMetaData;
676693

694+
final CpuStackFrame cpuProfileRoot;
695+
677696
/// `true` if the CpuProfileData has tag-based roots.
678697
///
679698
/// This value is used during the bottom-up transformation to ensure that the
@@ -687,7 +706,7 @@ class CpuProfileData with Serializable {
687706
if (!processed) return <CpuStackFrame>[];
688707
return _callTreeRoots ??= [
689708
// Don't display the root node.
690-
..._cpuProfileRoot.children.map((e) => e.deepCopy()),
709+
for (final rootChild in cpuProfileRoot.children) rootChild.deepCopy(),
691710
];
692711
}
693712

@@ -703,49 +722,23 @@ class CpuProfileData with Serializable {
703722
assert(_bottomUpRoots == null);
704723
_bottomUpRoots = await BottomUpTransformer<CpuStackFrame>()
705724
.bottomUpRootsFor(
706-
topDownRoot: _cpuProfileRoot,
725+
topDownRoot: cpuProfileRoot,
707726
mergeSamples: mergeCpuProfileRoots,
708727
rootedAtTags: rootedAtTags,
709728
);
710729
}
711730

712731
List<CpuStackFrame>? _bottomUpRoots;
713732

714-
CpuStackFrame get cpuProfileRoot => _cpuProfileRoot;
715-
716-
Iterable<String> get userTags {
717-
if (_userTags != null) {
718-
return _userTags!;
719-
}
720-
final tags = <String>{};
721-
for (final cpuSample in cpuSamples) {
722-
final tag = cpuSample.userTag;
723-
if (tag != null) {
724-
tags.add(tag);
725-
}
726-
}
727-
_userTags = tags;
728-
return _userTags!;
729-
}
730-
731-
Iterable<String> get vmTags {
732-
if (_vmTags != null) {
733-
return _vmTags!;
734-
}
735-
final tags = <String>{};
736-
for (final cpuSample in cpuSamples) {
737-
final tag = cpuSample.vmTag;
738-
if (tag != null) {
739-
tags.add(tag);
740-
}
741-
}
742-
return _vmTags = tags;
743-
}
744-
745-
Iterable<String>? _userTags;
746-
Iterable<String>? _vmTags;
733+
late final Iterable<String> userTags = {
734+
for (final cpuSample in cpuSamples)
735+
if (cpuSample.userTag case final userTag?) userTag,
736+
};
747737

748-
late final CpuStackFrame _cpuProfileRoot;
738+
late final Iterable<String> vmTags = {
739+
for (final cpuSample in cpuSamples)
740+
if (cpuSample.vmTag case final vmTag?) vmTag,
741+
};
749742

750743
CpuStackFrame? selectedStackFrame;
751744

@@ -755,24 +748,20 @@ class CpuProfileData with Serializable {
755748
_samplePeriodKey: profileMetaData.samplePeriod,
756749
_sampleCountKey: profileMetaData.sampleCount,
757750
_stackDepthKey: profileMetaData.stackDepth,
758-
if (profileMetaData.time?.start != null)
759-
_timeOriginKey: profileMetaData.time!.start!.inMicroseconds,
760-
if (profileMetaData.time?.duration != null)
761-
_timeExtentKey: profileMetaData.time!.duration.inMicroseconds,
751+
if (profileMetaData.time?.start case final startTime?)
752+
_timeOriginKey: startTime.inMicroseconds,
753+
if (profileMetaData.time?.duration case final duration?)
754+
_timeExtentKey: duration.inMicroseconds,
762755
_stackFramesKey: stackFramesJson,
763756
_traceEventsKey: cpuSamples.map((sample) => sample.toJson).toList(),
764757
};
765758

766759
bool get isEmpty => profileMetaData.sampleCount == 0;
767760

768761
@visibleForTesting
769-
Map<String, Object?> get stackFramesJson {
770-
final framesJson = <String, Object?>{};
771-
for (final sf in stackFrames.values) {
772-
framesJson.addAll(sf.toJson);
773-
}
774-
return framesJson;
775-
}
762+
Map<String, Object?> get stackFramesJson => {
763+
for (final sf in stackFrames.values) ...sf.toJson,
764+
};
776765
}
777766

778767
extension type _CpuProfileDataJson(Map<String, Object?> json) {
@@ -978,7 +967,7 @@ class CpuStackFrame extends TreeNode<CpuStackFrame>
978967

979968
@override
980969
String get tooltip {
981-
var prefix = '';
970+
final String? prefix;
982971
if (isNative) {
983972
prefix = '[Native]';
984973
} else if (isDartCore) {
@@ -987,8 +976,10 @@ class CpuStackFrame extends TreeNode<CpuStackFrame>
987976
prefix = '[Flutter]';
988977
} else if (isTag) {
989978
prefix = '[Tag]';
979+
} else {
980+
prefix = null;
990981
}
991-
final nameWithPrefix = [prefix, name].join(' ');
982+
final nameWithPrefix = [?prefix, name].join(' ');
992983
return [
993984
nameWithPrefix,
994985
durationText(totalTime),
@@ -1074,7 +1065,7 @@ class CpuStackFrame extends TreeNode<CpuStackFrame>
10741065
CpuProfileData.resolvedUrlKey: rawUrl,
10751066
CpuProfileData.resolvedPackageUriKey: packageUri,
10761067
CpuProfileData.sourceLineKey: sourceLine,
1077-
if (parentId != null) CpuProfileData.parentIdKey: parentId,
1068+
CpuProfileData.parentIdKey: ?parentId,
10781069
},
10791070
};
10801071

packages/devtools_app/lib/src/screens/profiler/cpu_profile_service.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extension CpuProfilerExtension on VmService {
3737
const kSamples = 'samples';
3838
const kCodeStack = '_codeStack';
3939

40-
final rawSamples = (cpuSamples.json![kSamples] as List)
40+
final rawSamples = (cpuSamples.json![kSamples] as List<Object?>)
4141
.cast<Map<String, Object?>>();
4242

4343
bool buildCodeProfile = false;
@@ -73,7 +73,7 @@ extension CpuProfilerExtension on VmService {
7373
);
7474
}
7575

76-
Future clearSamples() {
76+
Future<void> clearSamples() {
7777
return serviceConnection.serviceManager.service!.clearCpuSamples(
7878
serviceConnection
7979
.serviceManager

packages/devtools_app/lib/src/screens/profiler/sampling_rate.dart

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,9 @@ enum CpuSamplingRate {
3535
}
3636

3737
extension CpuSamplingRateExtension on CpuSamplingRate {
38-
static CpuSamplingRate fromValue(String value) {
39-
switch (value) {
40-
case lowProfilePeriod:
41-
return CpuSamplingRate.low;
42-
case highProfilePeriod:
43-
return CpuSamplingRate.high;
44-
case mediumProfilePeriod:
45-
default:
46-
return CpuSamplingRate.medium;
47-
}
48-
}
38+
static CpuSamplingRate fromValue(String value) => switch (value) {
39+
lowProfilePeriod => CpuSamplingRate.low,
40+
highProfilePeriod => CpuSamplingRate.high,
41+
mediumProfilePeriod || _ => CpuSamplingRate.medium,
42+
};
4943
}

0 commit comments

Comments
 (0)