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

Side by Side Diff: tools/perf/metrics/timeline.py

Issue 199733007: Remove start & stop logic from timeline_metric. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 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 unified diff | Download patch
« no previous file with comments | « tools/perf/measurements/timeline_controller.py ('k') | tools/perf/metrics/timeline_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 import collections 4 import collections
5 import itertools
6 5
7 from metrics import Metric 6 from metrics import Metric
8 from telemetry.core.timeline.model import TimelineModel
9 from telemetry.core.timeline import bounds 7 from telemetry.core.timeline import bounds
10 from telemetry.page import page_measurement
11
12 # All tracing categories not disabled-by-default
13 DEFAULT_TRACE_CATEGORIES = None
14
15 # Categories for absolute minimum overhead tracing. This contains no
16 # sub-traces of thread tasks, so it's only useful for capturing the
17 # cpu-time spent on threads (as well as needed benchmark traces)
18 MINIMAL_TRACE_CATEGORIES = ("toplevel,"
19 "benchmark,"
20 "webkit.console,"
21 "trace_event_overhead")
22
23 class MissingFramesError(page_measurement.MeasurementFailure):
24 def __init__(self):
25 super(MissingFramesError, self).__init__(
26 'No frames found in trace. Unable to normalize results.')
27 8
28 9
29 class TimelineMetric(Metric): 10 class TimelineMetric(Metric):
30 def __init__(self): 11 def __init__(self, model=None, renderer_process=None, action_ranges=None):
31 """ Initializes a TimelineMetric object. 12 """ Initializes a TimelineMetric object.
32 """ 13 """
33 super(TimelineMetric, self).__init__() 14 super(TimelineMetric, self).__init__()
34 self.trace_categories = DEFAULT_TRACE_CATEGORIES
35 self._model = None
36 self._renderer_process = None
37 self._actions = []
38 self._action_ranges = []
39
40 def Start(self, page, tab):
41 """Starts gathering timeline data.
42
43 """
44 self._model = None
45 if not tab.browser.supports_tracing:
46 raise Exception('Not supported')
47 if self.trace_categories:
48 categories = [self.trace_categories] + \
49 page.GetSyntheticDelayCategories()
50 else:
51 categories = page.GetSyntheticDelayCategories()
52 tab.browser.StartTracing(','.join(categories))
53
54 def Stop(self, page, tab):
55 timeline_data = tab.browser.StopTracing()
56 self._model = TimelineModel(timeline_data)
57 self._renderer_process = self._model.GetRendererProcessFromTab(tab)
58 self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model)
59 for action in self._actions ]
60 # Make sure no action ranges overlap
61 for combo in itertools.combinations(self._action_ranges, 2):
62 assert not combo[0].Intersects(combo[1])
63
64 def AddActionToIncludeInMetric(self, action):
65 self._actions.append(action)
66
67 @property
68 def model(self):
69 return self._model
70
71 @model.setter
72 def model(self, model):
73 self._model = model 15 self._model = model
74 16 self._renderer_process = renderer_process
75 @property 17 self._action_ranges = action_ranges if action_ranges else []
76 def renderer_process(self):
77 return self._renderer_process
78
79 @renderer_process.setter
80 def renderer_process(self, p):
81 self._renderer_process = p
82 18
83 def AddResults(self, tab, results): 19 def AddResults(self, tab, results):
84 return 20 return
85 21
86 22
87 class LoadTimesTimelineMetric(TimelineMetric): 23 class LoadTimesTimelineMetric(TimelineMetric):
88 def __init__(self): 24 def __init__(self, model=None, renderer_process=None, action_ranges=None):
89 super(LoadTimesTimelineMetric, self).__init__() 25 super(LoadTimesTimelineMetric, self).__init__(model, renderer_process,
26 action_ranges)
90 self.report_main_thread_only = True 27 self.report_main_thread_only = True
91 28
92 def AddResults(self, _, results): 29 def AddResults(self, _, results):
93 assert self._model 30 assert self._model
94 if self.report_main_thread_only: 31 if self.report_main_thread_only:
95 thread_filter = 'CrRendererMain' 32 thread_filter = 'CrRendererMain'
96 else: 33 else:
97 thread_filter = None 34 thread_filter = None
98 35
99 events_by_name = collections.defaultdict(list) 36 events_by_name = collections.defaultdict(list)
100 37
101 for thread in self.renderer_process.threads.itervalues(): 38 for thread in self._renderer_process.threads.itervalues():
102 39
103 if thread_filter and not thread.name in thread_filter: 40 if thread_filter and not thread.name in thread_filter:
104 continue 41 continue
105 42
106 thread_name = thread.name.replace('/','_') 43 thread_name = thread.name.replace('/','_')
107 events = thread.all_slices 44 events = thread.all_slices
108 45
109 for e in events: 46 for e in events:
110 events_by_name[e.name].append(e) 47 events_by_name[e.name].append(e)
111 48
112 for event_name, event_group in events_by_name.iteritems(): 49 for event_name, event_group in events_by_name.iteritems():
113 times = [event.self_time for event in event_group] 50 times = [event.self_time for event in event_group]
114 total = sum(times) 51 total = sum(times)
115 biggest_jank = max(times) 52 biggest_jank = max(times)
116 53
117 # Results objects cannot contain the '.' character, so remove that here. 54 # Results objects cannot contain the '.' character, so remove that here.
118 sanitized_event_name = event_name.replace('.', '_') 55 sanitized_event_name = event_name.replace('.', '_')
119 56
120 full_name = thread_name + '|' + sanitized_event_name 57 full_name = thread_name + '|' + sanitized_event_name
121 results.Add(full_name, 'ms', total) 58 results.Add(full_name, 'ms', total)
122 results.Add(full_name + '_max', 'ms', biggest_jank) 59 results.Add(full_name + '_max', 'ms', biggest_jank)
123 results.Add(full_name + '_avg', 'ms', total / len(times)) 60 results.Add(full_name + '_avg', 'ms', total / len(times))
124 61
125 for counter_name, counter in self.renderer_process.counters.iteritems(): 62 for counter_name, counter in self._renderer_process.counters.iteritems():
126 total = sum(counter.totals) 63 total = sum(counter.totals)
127 64
128 # Results objects cannot contain the '.' character, so remove that here. 65 # Results objects cannot contain the '.' character, so remove that here.
129 sanitized_counter_name = counter_name.replace('.', '_') 66 sanitized_counter_name = counter_name.replace('.', '_')
130 67
131 results.Add(sanitized_counter_name, 'count', total) 68 results.Add(sanitized_counter_name, 'count', total)
132 results.Add(sanitized_counter_name + '_avg', 'count', 69 results.Add(sanitized_counter_name + '_avg', 'count',
133 total / float(len(counter.totals))) 70 total / float(len(counter.totals)))
134 71
135 72
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 'ms', self_time_result) 205 'ms', self_time_result)
269 all_measured_time = sum(all_self_times) 206 all_measured_time = sum(all_self_times)
270 all_action_time = sum([action.bounds for action in self.action_ranges]) 207 all_action_time = sum([action.bounds for action in self.action_ranges])
271 idle_time = max(0, all_action_time - all_measured_time) 208 idle_time = max(0, all_action_time - all_measured_time)
272 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 209 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0
273 results.Add(ThreadDetailResultName(self.name, "idle"), 210 results.Add(ThreadDetailResultName(self.name, "idle"),
274 'ms', idle_time_result) 211 'ms', idle_time_result)
275 212
276 213
277 class ThreadTimesTimelineMetric(TimelineMetric): 214 class ThreadTimesTimelineMetric(TimelineMetric):
278 def __init__(self): 215 def __init__(self, model=None, renderer_process=None, action_ranges=None):
279 super(ThreadTimesTimelineMetric, self).__init__() 216 super(ThreadTimesTimelineMetric, self).__init__(model, renderer_process,
217 action_ranges)
280 # Minimal traces, for minimum noise in CPU-time measurements. 218 # Minimal traces, for minimum noise in CPU-time measurements.
281 self.trace_categories = MINIMAL_TRACE_CATEGORIES
282 self.results_to_report = AllThreads 219 self.results_to_report = AllThreads
283 self.details_to_report = NoThreads 220 self.details_to_report = NoThreads
284 221
285 def Start(self, page, tab):
286 # We need the other traces in order to have any details to report.
287 if not self.details_to_report == NoThreads:
288 self.trace_categories = DEFAULT_TRACE_CATEGORIES
289 super(ThreadTimesTimelineMetric, self).Start(page, tab)
290
291 def CountSlices(self, slices, substring): 222 def CountSlices(self, slices, substring):
292 count = 0 223 count = 0
293 for event in slices: 224 for event in slices:
294 if substring in event.name: 225 if substring in event.name:
295 count += 1 226 count += 1
296 return count 227 return count
297 228
298 def AddResults(self, tab, results): 229 def AddResults(self, tab, results):
299 # We need at least one action or we won't count any slices. 230 # We need at least one action or we won't count any slices.
300 assert len(self._action_ranges) > 0 231 assert len(self._action_ranges) > 0
(...skipping 24 matching lines...) Expand all
325 num_frames = self.CountSlices(frame_slices, FrameTraceName) 256 num_frames = self.CountSlices(frame_slices, FrameTraceName)
326 257
327 # Report the desired results and details. 258 # Report the desired results and details.
328 for thread_results in thread_category_results.values(): 259 for thread_results in thread_category_results.values():
329 if thread_results.name in self.results_to_report: 260 if thread_results.name in self.results_to_report:
330 thread_results.AddResults(num_frames, results) 261 thread_results.AddResults(num_frames, results)
331 # TOOD(nduca): When generic results objects are done, this special case 262 # TOOD(nduca): When generic results objects are done, this special case
332 # can be replaced with a generic UI feature. 263 # can be replaced with a generic UI feature.
333 if thread_results.name in self.details_to_report: 264 if thread_results.name in self.details_to_report:
334 thread_results.AddDetailedResults(num_frames, results) 265 thread_results.AddDetailedResults(num_frames, results)
OLDNEW
« no previous file with comments | « tools/perf/measurements/timeline_controller.py ('k') | tools/perf/metrics/timeline_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698