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

Side by Side Diff: tools/tracemerge.dart

Issue 109803002: Profiler Take 2 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 // Merge multiple isolate profiler tracing dumps into one.
6 * Operations on collections.
7 */
8 library dart.collection_helpers.algorithms;
9 6
10 import "dart:math" show Random; 7 import 'dart:convert';
11 8 import 'dart:io';
12 /** Version of [binarySearch] optimized for comparable keys */
13 int _comparableBinarySearch(List<Comparable> list, Comparable key) {
14 int min = 0;
15 int max = list.length;
16 while (min < max) {
17 int mid = min + ((max - min) >> 1);
18 var element = list[mid];
19 int comp = element.compareTo(key);
20 if (comp == 0) return mid;
21 if (comp < 0) {
22 min = mid + 1;
23 } else {
24 max = mid;
25 }
26 }
27 return -1;
28 }
29
30 /**
31 * Returns a position of the [key] in [sortedList], if it is there.
32 *
33 * If the list isn't sorted according to the [compare] function, the result
34 * is unpredictable.
35 *
36 * If [compare] is omitted, it defaults to calling [Comparable.compareTo] on
37 * the objects.
38 *
39 * Returns -1 if [key] is not in the list by default.
40 */
41 int binarySearch(List sortedList, var key,
42 { int compare(var a, var b) }) {
43 if (compare == null) {
44 return _comparableBinarySearch(sortedList, key);
45 }
46 int min = 0;
47 int max = sortedList.length;
48 while (min < max) {
49 int mid = min + ((max - min) >> 1);
50 var element = sortedList[mid];
51 int comp = compare(element, key);
52 if (comp == 0) return mid;
53 if (comp < 0) {
54 min = mid + 1;
55 } else {
56 max = mid;
57 }
58 }
59 return -1;
60 }
61
62
63 /**
64 * Shuffles a list randomly.
65 *
66 * A sub-range of a list can be shuffled by providing [start] and [end].
67 */
68 void shuffle(List list, [int start = 0, int end = null]) {
69 Random random = new Random();
70 if (end == null) end = list.length;
71 int length = end - start;
72 while (length > 1) {
73 int pos = random.nextInt(length);
74 length--;
75 var tmp1 = list[start + pos];
76 list[start + pos] = list[start + length];
77 list[start + length] = tmp1;
78 }
79 }
80
81
82 /**
83 * Reverses a list, or a part of a list, in-place.
84 */
85 void reverse(List list, [int start = 0, int end = null]) {
86 if (end == null) end = list.length;
87 _reverse(list, start, end);
88 }
89
90 // Internal helper function that assumes valid arguments.
91 void _reverse(List list, int start, int end) {
92 for (int i = start, j = end - 1; i < j; i++, j--) {
93 var tmp = list[i];
94 list[i] = list[j];
95 list[j] = tmp;
96 }
97 }
98 9
99 /** 10 /**
100 * Sort a list using insertion sort. 11 * Sort a list using insertion sort.
101 * 12 *
102 * Insertion sort is a simple sorting algorithm. For `n` elements it does on 13 * Insertion sort is a simple sorting algorithm. For `n` elements it does on
103 * the order of `n * log(n)` comparisons but up to `n` squared moves. The 14 * the order of `n * log(n)` comparisons but up to `n` squared moves. The
104 * sorting is performed in-place, without using extra memory. 15 * sorting is performed in-place, without using extra memory.
105 * 16 *
106 * For short lists the many moves have less impact than the simple algorithm, 17 * For short lists the many moves have less impact than the simple algorithm,
107 * and it is often the favored sorting algorithm for short lists. 18 * and it is often the favored sorting algorithm for short lists.
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 target.setRange(targetOffset, targetOffset + (firstEnd - cursor1), 203 target.setRange(targetOffset, targetOffset + (firstEnd - cursor1),
293 firstList, cursor1); 204 firstList, cursor1);
294 return; 205 return;
295 } 206 }
296 } 207 }
297 // First list empties first. Reached by break above. 208 // First list empties first. Reached by break above.
298 target[targetOffset++] = secondElement; 209 target[targetOffset++] = secondElement;
299 target.setRange(targetOffset, targetOffset + (secondEnd - cursor2), 210 target.setRange(targetOffset, targetOffset + (secondEnd - cursor2),
300 secondList, cursor2); 211 secondList, cursor2);
301 } 212 }
213
214 class TraceMerge {
215 Map _processes = {};
216 List _metaEvents = [];
217
218 void _processEventsFromFile(String name) {
219 var file = new File(name);
220 var events = [];
221 try {
222 var contents = file.readAsStringSync();
223 events = JSON.decode(contents);
224 } catch (e) {
225 print('Exception for $name $e');
226 }
227 _processEvents(events);
228 }
229
230 List _findOrAddProcessThread(pid, tid) {
231 var process = _processes[pid];
232 if (process == null) {
233 process = {};
234 _processes[pid] = process;
235 }
236 var thread = process[tid];
237 if (thread == null) {
238 thread = [];
239 process[tid] = thread;
240 }
241 return thread;
242 }
243
244 void _processEvents(List events) {
245 for (var i = 0; i < events.length; i++) {
246 Map event = events[i];
247 if (event['ph'] == 'M') {
248 _metaEvents.add(event);
249 } else {
250 var pid = event['pid'];
251 if (pid == null) {
252 throw "No pid in ${event}";
253 }
254 var tid = event['tid'];
255 if (tid == null) {
256 throw "No tid in ${event}";
257 }
258 var thread = _findOrAddProcessThread(pid, tid);
259 if (thread == null) {
260 throw "No thread list returned.";
261 }
262 thread.add(event);
263 }
264 }
265 }
266
267 int _compare(Map a, Map b) {
268 if (a['ts'] > b['ts']) {
269 return 1;
270 } else if (a['ts'] < b['ts']) {
271 return -1;
272 }
273 return 0;
274 }
275
276 void _sortEvents() {
277 _processes.forEach((k, Map process) {
278 process.forEach((k, List thread) {
279 mergeSort(thread, compare:_compare);
280 });
281 });
282 }
283
284 void _mergeEventsForThread(List thread) {
285 List<Map> stack = [];
286 int stackDepth = 0;
287 thread.forEach((event) {
288 if (event['ph'] == 'B') {
289 if (stackDepth == stack.length) {
290 stack.add(null);
291 }
292 stackDepth++;
293 var end_event = stack[stackDepth - 1];
294 if (end_event != null) {
295 if (end_event['name'] == event['name'] && stackDepth > 1) {
296 // Kill these events.
297 // event['dead'] = true;
298 // end_event['dead'] = true;
299 }
300 }
301 } else {
302 if (event['ph'] != 'E') {
303 throw 'Expected E event: ${event}';
304 }
305 if (stackDepth <= 0) {
306 throw 'Stack out of sync ${event}.';
307 }
308 stackDepth--;
309 stack[stackDepth] = event;
310 }
311 });
312 }
313
314 void _mergeEvents() {
315 _processes.forEach((k, Map process) {
316 process.forEach((k, List thread) {
317 _mergeEventsForThread(thread);
318 });
319 });
320 }
321
322 void writeEventsToFile(String name) {
323 var file = new File(name);
324 List final_events = _metaEvents;
325 _processes.forEach((pid, Map process) {
326 process.forEach((tid, List thread) {
327 thread.forEach((event) {
328 if (event['dead'] == null) {
329 // Not dead.
330 final_events.add(event);
331 }
332 });
333 });
334 });
335 file.writeAsStringSync(JSON.encode(final_events));
336 }
337
338 void merge(List<String> inputs) {
339 for (var i = 0; i < inputs.length; i++) {
340 _processEventsFromFile(inputs[i]);
341 }
342 _sortEvents();
343 _mergeEvents();
344 }
345 }
346
347 main(List<String> arguments) {
348 if (arguments.length < 2) {
349 print('${Platform.executable} ${Platform.script} <output> <inputs>');
350 return;
351 }
352 String output = arguments[0];
353 List<String> inputs = new List<String>();
354 for (var i = 1; i < arguments.length; i++) {
355 inputs.add(arguments[i]);
356 }
357 print('Merging $inputs into $output.');
358 TraceMerge tm = new TraceMerge();
359 tm.merge(inputs);
360 tm.writeEventsToFile(output);
361 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698