OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2016 The Chromium Authors. All rights reserved. | 3 Copyright 2016 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" | 8 <link rel="import" |
9 href="/tracing/extras/chrome/chrome_user_friendly_category_driver.html"> | 9 href="/tracing/extras/chrome/chrome_user_friendly_category_driver.html"> |
10 <link rel="import" href="/tracing/metrics/metric_registry.html"> | 10 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
11 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> | 11 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
12 <link rel="import" href="/tracing/value/histogram.html"> | 12 <link rel="import" href="/tracing/value/histogram.html"> |
13 <link rel="import" href="/tracing/value/value.html"> | 13 <link rel="import" href="/tracing/value/value.html"> |
14 | 14 |
15 <script> | 15 <script> |
16 'use strict'; | 16 'use strict'; |
17 | 17 |
18 tr.exportTo('tr.metrics.sh', function() { | 18 tr.exportTo('tr.metrics.sh', function() { |
19 var LONG_TASK_MS = 50; | 19 var LONG_TASK_MS = 50; |
20 | 20 |
21 // Anything longer than this should be so rare that its length beyond this is | 21 // Anything longer than this should be so rare that its length beyond this is |
22 // uninteresting. | 22 // uninteresting. |
23 var LONGEST_TASK_MS = 1000; | 23 var LONGEST_TASK_MS = 1000; |
24 | 24 |
25 var timeDurationInMs_smallerIsBetter = | |
26 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter; | |
27 | |
28 /** | 25 /** |
29 * This helper function calls |cb| for each of the top-level tasks on the | 26 * This helper function calls |cb| for each of the top-level tasks on the |
30 * given thread in the given range whose duration is longer than LONG_TASK_MS. | 27 * given thread in the given range whose duration is longer than LONG_TASK_MS. |
31 * | 28 * |
32 * @param {tr.model.Thread} thread | 29 * @param {tr.model.Thread} thread |
33 * @param {tr.b.Range=} opt_range | 30 * @param {tr.b.Range=} opt_range |
34 * @param {function()} cb | 31 * @param {function()} cb |
35 * @param {Object=} opt_this | 32 * @param {Object=} opt_this |
36 */ | 33 */ |
37 function iterateLongTopLevelTasksOnThreadInRange( | 34 function iterateLongTopLevelTasksOnThreadInRange( |
(...skipping 22 matching lines...) Expand all Loading... |
60 var modelHelper = model.getOrCreateHelper( | 57 var modelHelper = model.getOrCreateHelper( |
61 tr.model.helpers.ChromeModelHelper); | 58 tr.model.helpers.ChromeModelHelper); |
62 tr.b.dictionaryValues(modelHelper.rendererHelpers).forEach( | 59 tr.b.dictionaryValues(modelHelper.rendererHelpers).forEach( |
63 function(rendererHelper) { | 60 function(rendererHelper) { |
64 if (!rendererHelper.mainThread) | 61 if (!rendererHelper.mainThread) |
65 return; | 62 return; |
66 cb.call(opt_this, rendererHelper.mainThread); | 63 cb.call(opt_this, rendererHelper.mainThread); |
67 }); | 64 }); |
68 } | 65 } |
69 | 66 |
70 var LONG_TASK_NUMERIC_BUILDER = tr.v.NumericBuilder.createLinear( | |
71 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter, | |
72 tr.b.Range.fromExplicitRange(LONG_TASK_MS, LONGEST_TASK_MS), 50); | |
73 | |
74 // This range spans several orders of magnitude, and the data is likely to | |
75 // form an exponential distribution, so use exponential bins in order to | |
76 // prevent the lowest bin from containing almost all of the samples. | |
77 // See also most UMA histograms that are exponential for similar reasons. | |
78 var SLICE_NUMERIC_BUILDER = tr.v.NumericBuilder.createExponential( | |
79 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter, | |
80 tr.b.Range.fromExplicitRange(0.1, LONGEST_TASK_MS), 50); | |
81 | |
82 /** | 67 /** |
83 * This metric directly measures long tasks on renderer main threads. | 68 * This metric directly measures long tasks on renderer main threads. |
84 * This metric requires only the 'toplevel' tracing category. | 69 * This metric requires only the 'toplevel' tracing category. |
85 * | 70 * |
86 * @param {!tr.v.ValueSet} values | 71 * @param {!tr.v.ValueSet} values |
87 * @param {!tr.model.Model} model | 72 * @param {!tr.model.Model} model |
88 * @param {!Object=} opt_options | 73 * @param {!Object=} opt_options |
89 */ | 74 */ |
90 function longTasksMetric(values, model, opt_options) { | 75 function longTasksMetric(values, model, opt_options) { |
91 var rangeOfInterest = opt_options ? opt_options.rangeOfInterest : undefined; | 76 var rangeOfInterest = opt_options ? opt_options.rangeOfInterest : undefined; |
92 var longTaskNumeric = LONG_TASK_NUMERIC_BUILDER.build(); | 77 var longTaskNumeric = new |
| 78 tr.v.Histogram(tr.v.Unit.byName.timeDurationInMs_smallerIsBetter, |
| 79 tr.v.HistogramBinBoundaries.createLinear( |
| 80 LONG_TASK_MS, LONGEST_TASK_MS, 40)); |
93 var slices = new tr.model.EventSet(); | 81 var slices = new tr.model.EventSet(); |
94 iterateRendererMainThreads(model, function(thread) { | 82 iterateRendererMainThreads(model, function(thread) { |
95 iterateLongTopLevelTasksOnThreadInRange( | 83 iterateLongTopLevelTasksOnThreadInRange( |
96 thread, rangeOfInterest, function(task) { | 84 thread, rangeOfInterest, function(task) { |
97 longTaskNumeric.add(task.duration, tr.v.d.DiagnosticMap.fromObject({ | 85 longTaskNumeric.add(task.duration, tr.v.d.DiagnosticMap.fromObject({ |
98 relatedEvents: new tr.v.d.RelatedEventSet([task])})); | 86 relatedEvents: new tr.v.d.RelatedEventSet([task])})); |
99 slices.push(task); | 87 slices.push(task); |
100 slices.addEventSet(task.descendentSlices); | 88 slices.addEventSet(task.descendentSlices); |
101 }); | 89 }); |
102 }); | 90 }); |
103 var options = {description: 'durations of long tasks'}; | 91 var options = {description: 'durations of long tasks'}; |
104 var longTaskValue = new tr.v.NumericValue( | 92 var longTaskValue = new tr.v.NumericValue( |
105 'long tasks', longTaskNumeric, options); | 93 'long tasks', longTaskNumeric, options); |
106 values.addValue(longTaskValue); | 94 values.addValue(longTaskValue); |
| 95 |
| 96 var sampleForEvent = undefined; |
107 var composition = tr.v.d.Composition.buildFromEvents( | 97 var composition = tr.v.d.Composition.buildFromEvents( |
108 values, 'long tasks ', slices, SLICE_NUMERIC_BUILDER, | 98 values, 'long tasks ', slices, |
109 e => (model.getUserFriendlyCategoryFromEvent(e) || 'unknown')); | 99 e => (model.getUserFriendlyCategoryFromEvent(e) || 'unknown'), |
| 100 tr.v.Unit.byName.timeDurationInMs_smallerIsBetter, sampleForEvent, |
| 101 tr.v.HistogramBinBoundaries.createExponential(1, LONGEST_TASK_MS, 40)); |
110 composition.colorScheme = | 102 composition.colorScheme = |
111 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER; | 103 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER; |
112 longTaskValue.diagnostics.set('category', composition); | 104 longTaskValue.diagnostics.set('category', composition); |
113 } | 105 } |
114 | 106 |
115 tr.metrics.MetricRegistry.register(longTasksMetric, { | 107 tr.metrics.MetricRegistry.register(longTasksMetric, { |
116 supportsRangeOfInterest: true | 108 supportsRangeOfInterest: true |
117 }); | 109 }); |
118 | 110 |
119 return { | 111 return { |
120 longTasksMetric: longTasksMetric, | 112 longTasksMetric: longTasksMetric, |
121 iterateLongTopLevelTasksOnThreadInRange: | 113 iterateLongTopLevelTasksOnThreadInRange: |
122 iterateLongTopLevelTasksOnThreadInRange, | 114 iterateLongTopLevelTasksOnThreadInRange, |
123 iterateRendererMainThreads: iterateRendererMainThreads, | 115 iterateRendererMainThreads: iterateRendererMainThreads, |
124 LONG_TASK_MS: LONG_TASK_MS, | 116 LONG_TASK_MS: LONG_TASK_MS, |
125 LONGEST_TASK_MS: LONGEST_TASK_MS | 117 LONGEST_TASK_MS: LONGEST_TASK_MS |
126 }; | 118 }; |
127 }); | 119 }); |
128 </script> | 120 </script> |
OLD | NEW |