Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1765)

Unified Diff: pkg/compiler/tool/stats/print_summary.dart

Issue 1220043005: dart2js send stats, includes: (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/tool/stats/print_summary.dart
diff --git a/pkg/compiler/tool/stats/print_summary.dart b/pkg/compiler/tool/stats/print_summary.dart
new file mode 100644
index 0000000000000000000000000000000000000000..cae6b8f6c7e9b3531906c0586bcaa06a8b1ebfa4
--- /dev/null
+++ b/pkg/compiler/tool/stats/print_summary.dart
@@ -0,0 +1,210 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility to display [GlobalResult] as a table on the command line.
+library compiler.tool.stats.print_summary;
+
+import 'dart:io';
+import 'dart:convert';
+import 'dart:math' show max;
+import 'package:compiler/src/stats/stats.dart';
+
+main(args) {
+ var file = args.length > 0 ? args[0] : 'out.js.stats.json';
+ var results = GlobalResult.fromJson(
+ JSON.decode(new File(file).readAsStringSync()));
+ print(formatAsTable(results));
+}
+
+/// Formats [results] as a table.
+String formatAsTable(GlobalResult results) {
+ var visitor = new _Counter();
+ results.accept(visitor);
+ var table = new _Table();
+ table.declareColumn('bundle');
+
+ int colorIndex = 0;
+ visitAllMetrics((m, _) {
+ if (m is GroupedMetric) colorIndex = (colorIndex + 1) % _groupColors.length;
+ table.declareColumn(m.name,
+ abbreviate: true, color: _groupColors[colorIndex]);
+ });
+ table.addHeader();
+ appendCount(n) => table.addEntry(n == null ? 0 : n);
+
+ for (var bundle in visitor.bundleTotals.keys) {
+ table.addEntry(bundle);
+ visitAllMetrics(
+ (m, _) => appendCount(visitor.bundleTotals[bundle].counters[m]));
+ }
+ table.addEmptyRow();
+ table.addHeader();
+ table.addEntry('total');
+ visitAllMetrics((m, _) => appendCount(visitor.totals.counters[m]));
+
+ appendPercent(count, total) {
+ if (count == null) count = 0;
+ if (total == null) total = 0;
+ var percent = count * 100 / total;
+ table.addEntry(percent == 100 ? 100 : percent.toStringAsFixed(2));
+ }
+
+ table.addEntry('%');
+ visitAllMetrics((metric, parents) {
+ if (parents == null || parents.isEmpty) {
+ table.addEntry(100);
+ } else {
+ appendPercent(visitor.totals.counters[metric],
+ visitor.totals.counters[parents[0]]);
+ }
+ });
+
+ return table.toString();
+}
+
+/// Visitor that adds up results for all functions in libraries, and all
+/// libraries in a bundle.
+class _Counter extends RecursiveResultVisitor {
+ Map<String, Measurements> bundleTotals = {};
+ Measurements currentBundleTotals;
+ Measurements totals = new Measurements();
+
+ visitBundle(BundleResult bundle) {
+ currentBundleTotals =
+ bundleTotals.putIfAbsent(bundle.name, () => new Measurements());
+ super.visitBundle(bundle);
+ totals.addFrom(currentBundleTotals);
+ }
+
+ visitFunction(FunctionResult function) {
+ currentBundleTotals.addFrom(function.measurements);
+ }
+}
+
+/// Helper class to combine all the information in table form.
+class _Table {
+ int _totalColumns = 0;
+ int get totalColumns => _totalColumns;
+
+ /// Abbreviations, used to make headers shorter.
+ Map<String, String> abbreviations = {};
+
+ /// Width of each column.
+ List<int> widths = <int>[];
+
+ /// The header for each column (`header.length == totalColumns`).
+ List header = [];
+
+ /// The color for each column (`color.length == totalColumns`).
+ List colors = [];
+
+ /// Each row on the table. Note that all rows have the same size
+ /// (`rows[*].length == totalColumns`).
+ List<List> rows = [];
+
+ /// Columns to skip, for example, if they are all zero entries.
+ List<bool> _skipped = <bool>[];
+
+ /// Whether we started adding entries. Indicates that no more columns can be
+ /// added.
+ bool _sealed = false;
+
+ /// Current row being built by [addEntry].
+ List _currentRow;
+
+ /// Add a column with the given [name].
+ void declareColumn(String name,
+ {bool abbreviate: false, String color: _NO_COLOR}) {
+ assert(!_sealed);
+ var headerName = name;
+ if (abbreviate) {
+ // abbreviate the header by using only the initials of each word
+ headerName = name.split(' ')
+ .map((s) => s.substring(0, 1).toUpperCase()).join('');
+ while (abbreviations[headerName] != null) headerName = "$headerName'";
+ abbreviations[headerName] = name;
+ }
+ widths.add(max(5, headerName.length + 1));
+ header.add(headerName);
+ colors.add(color);
+ _skipped.add(_totalColumns > 0);
+ _totalColumns++;
+ }
+
+ /// Add an entry in the table, creating a new row each time [totalColumns]
+ /// entries are added.
+ void addEntry(entry) {
+ if (_currentRow == null) {
+ _sealed = true;
+ _currentRow = [];
+ }
+ int pos = _currentRow.length;
+ assert(pos < _totalColumns);
+
+ widths[pos] = max(widths[pos], '$entry'.length + 1);
+ _currentRow.add('$entry');
+ if (entry is int && entry != 0) {
+ _skipped[pos] = false;
+ }
+
+ if (pos + 1 == _totalColumns) {
+ rows.add(_currentRow);
+ _currentRow = [];
+ }
+ }
+
+ /// Add an empty row to divide sections of the table.
+ void addEmptyRow() {
+ var emptyRow = [];
+ for (int i = 0; i < _totalColumns; i++) {
+ emptyRow.add('-' * widths[i]);
+ }
+ rows.add(emptyRow);
+ }
+
+ /// Enter the header titles. OK to do so more than once in long tables.
+ void addHeader() {
+ rows.add(header);
+ }
+
+ /// Generates a string representation of the table to print on a terminal.
+ // TODO(sigmund): add also a .csv format
+ String toString() {
+ var sb = new StringBuffer();
+ sb.write('\n');
+ for (var row in rows) {
+ var lastColor = _NO_COLOR;
+ for (int i = 0; i < _totalColumns; i++) {
+ if (_skipped[i]) continue;
+ var entry = row[i];
+ var color = colors[i];
+ if (lastColor != color) {
+ sb.write(color);
+ lastColor = color;
+ }
+ // Align first column to the left, everything else to the right.
+ sb.write(
+ i == 0 ? entry.padRight(widths[i]) : entry.padLeft(widths[i] + 1));
+ }
+ if (lastColor != _NO_COLOR) sb.write(_NO_COLOR);
+ sb.write('\n');
+ }
+ sb.write('\nWhere:\n');
+ for (var id in abbreviations.keys) {
+ sb.write(' $id:'.padRight(7));
+ sb.write(' ${abbreviations[id]}\n');
+ }
+ return sb.toString();
+ }
+}
+
+const _groupColors = const [
+ _YELLOW_COLOR,
+ _NO_COLOR,
+];
+
+const _NO_COLOR = "\x1b[0m";
+const _GREEN_COLOR = "\x1b[32m";
+const _YELLOW_COLOR = "\x1b[33m";
+const _WHITE_COLOR = "\x1b[37m";

Powered by Google App Engine
This is Rietveld 408576698