generateHotspotReport method
String
generateHotspotReport(
- CpuSamples samples, {
- int topN = 10,
})
Implementation
String generateHotspotReport(CpuSamples samples, {int topN = 10}) {
final total = (samples.sampleCount ?? 0) < 1 ? 1 : samples.sampleCount!;
final functions = samples.functions ?? [];
final sorted = [...functions]
..sort(
(a, b) => (b.exclusiveTicks ?? 0).compareTo(a.exclusiveTicks ?? 0));
// Filter: keep only Dart user code
// Dart source files have resolvedUrl like "package:foo/bar.dart" or "file:///...dart"
// Native frames on Android have resolvedUrl like "/data/app/.../libflutter.so+0x..."
// Native frames on iOS have empty resolvedUrl or native lib paths
final user = sorted.where((f) {
final url = f.resolvedUrl ?? '';
final name = _formatName(f);
// Bracket notation = VM internal/native regardless of URL
if (name.startsWith('[')) return false;
// Must have a Dart source URL
if (url.isEmpty) return false;
if (!url.endsWith('.dart')) return false; // .so, .dylib, empty = not Dart
// Skip SDK internals
if (url.startsWith('dart:')) return false;
if (url.startsWith('org-dartlang-sdk:')) return false; // AOT compiled SDK
if (url.contains('org-dartlang-sdk')) return false;
// Skip Flutter framework (keep app code)
if (url.contains('packages/flutter/')) return false;
if (url.contains('pub.dartlang.org')) return false;
// Only keep app package code
if (!url.contains('package:') && !url.startsWith('file:')) return false;
return true;
}).take(topN).toList();
final windowSec =
((samples.timeExtentMicros ?? 0) / 1e6).toStringAsFixed(1);
final sb = StringBuffer();
sb.writeln('CPU Hotspots (${windowSec}s window, $total samples)');
sb.writeln('━' * 60);
sb.writeln('${'Rank'.padRight(6)}${'Self%'.padRight(8)}${'Total%'.padRight(9)}Function');
for (int i = 0; i < user.length; i++) {
final f = user[i];
final selfPct =
((f.exclusiveTicks ?? 0) / total * 100).toStringAsFixed(1).padLeft(5);
final totalPct =
((f.inclusiveTicks ?? 0) / total * 100).toStringAsFixed(1).padLeft(6);
final name = _formatName(f);
sb.writeln(' ${(i + 1).toString().padLeft(2)}. $selfPct% $totalPct% $name');
}
sb.writeln('');
sb.writeln(_advice(user, total));
return sb.toString();
}