| OLD | NEW |
| 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 | 5 |
| 6 from telemetry.web_perf.metrics import timeline_based_metric | 6 from telemetry.web_perf.metrics import timeline_based_metric |
| 7 from telemetry.value import scalar |
| 7 | 8 |
| 8 | 9 |
| 9 class LoadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): | 10 class LoadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): |
| 10 def __init__(self): | 11 def __init__(self): |
| 11 super(LoadTimesTimelineMetric, self).__init__() | 12 super(LoadTimesTimelineMetric, self).__init__() |
| 12 self.report_main_thread_only = True | 13 self.report_main_thread_only = True |
| 13 | 14 |
| 14 def AddResults(self, model, renderer_thread, interaction_records, results): | 15 def AddResults(self, model, renderer_thread, interaction_records, results): |
| 15 assert model | 16 assert model |
| 16 assert len(interaction_records) == 1, ( | 17 assert len(interaction_records) == 1, ( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 37 | 38 |
| 38 for event_name, event_group in events_by_name.iteritems(): | 39 for event_name, event_group in events_by_name.iteritems(): |
| 39 times = [event.self_time for event in event_group] | 40 times = [event.self_time for event in event_group] |
| 40 total = sum(times) | 41 total = sum(times) |
| 41 biggest_jank = max(times) | 42 biggest_jank = max(times) |
| 42 | 43 |
| 43 # Results objects cannot contain the '.' character, so remove that here. | 44 # Results objects cannot contain the '.' character, so remove that here. |
| 44 sanitized_event_name = event_name.replace('.', '_') | 45 sanitized_event_name = event_name.replace('.', '_') |
| 45 | 46 |
| 46 full_name = thread_name + '|' + sanitized_event_name | 47 full_name = thread_name + '|' + sanitized_event_name |
| 47 results.Add(full_name, 'ms', total) | 48 results.AddValue(scalar.ScalarValue( |
| 48 results.Add(full_name + '_max', 'ms', biggest_jank) | 49 results.current_page, full_name, 'ms', total)) |
| 49 results.Add(full_name + '_avg', 'ms', total / len(times)) | 50 results.AddValue(scalar.ScalarValue( |
| 51 results.current_page, full_name + '_max', 'ms', biggest_jank)) |
| 52 results.AddValue(scalar.ScalarValue( |
| 53 results.current_page, full_name + '_avg', 'ms', total / len(times))) |
| 50 | 54 |
| 51 for counter_name, counter in renderer_process.counters.iteritems(): | 55 for counter_name, counter in renderer_process.counters.iteritems(): |
| 52 total = sum(counter.totals) | 56 total = sum(counter.totals) |
| 53 | 57 |
| 54 # Results objects cannot contain the '.' character, so remove that here. | 58 # Results objects cannot contain the '.' character, so remove that here. |
| 55 sanitized_counter_name = counter_name.replace('.', '_') | 59 sanitized_counter_name = counter_name.replace('.', '_') |
| 56 | 60 |
| 57 results.Add(sanitized_counter_name, 'count', total) | 61 results.AddValue(scalar.ScalarValue( |
| 58 results.Add(sanitized_counter_name + '_avg', 'count', | 62 results.current_page, sanitized_counter_name, 'count', total)) |
| 59 total / float(len(counter.totals))) | 63 results.AddValue(scalar.ScalarValue( |
| 64 results.current_page, sanitized_counter_name + '_avg', 'count', |
| 65 total / float(len(counter.totals)))) |
| 60 | 66 |
| 61 # We want to generate a consistant picture of our thread usage, despite | 67 # We want to generate a consistant picture of our thread usage, despite |
| 62 # having several process configurations (in-proc-gpu/single-proc). | 68 # having several process configurations (in-proc-gpu/single-proc). |
| 63 # Since we can't isolate renderer threads in single-process mode, we | 69 # Since we can't isolate renderer threads in single-process mode, we |
| 64 # always sum renderer-process threads' times. We also sum all io-threads | 70 # always sum renderer-process threads' times. We also sum all io-threads |
| 65 # for simplicity. | 71 # for simplicity. |
| 66 TimelineThreadCategories = { | 72 TimelineThreadCategories = { |
| 67 "Chrome_InProcGpuThread": "GPU", | 73 "Chrome_InProcGpuThread": "GPU", |
| 68 "CrGpuMain" : "GPU", | 74 "CrGpuMain" : "GPU", |
| 69 "AsyncTransferThread" : "GPU_transfer", | 75 "AsyncTransferThread" : "GPU_transfer", |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 slices_in_actions.append(event) | 177 slices_in_actions.append(event) |
| 172 break | 178 break |
| 173 return slices_in_actions | 179 return slices_in_actions |
| 174 | 180 |
| 175 def AppendThreadSlices(self, thread): | 181 def AppendThreadSlices(self, thread): |
| 176 self.all_slices.extend(self.SlicesInActions(thread.all_slices)) | 182 self.all_slices.extend(self.SlicesInActions(thread.all_slices)) |
| 177 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices)) | 183 self.toplevel_slices.extend(self.SlicesInActions(thread.toplevel_slices)) |
| 178 | 184 |
| 179 def AddResults(self, num_frames, results): | 185 def AddResults(self, num_frames, results): |
| 180 cpu_per_frame = (float(self.cpu_time) / num_frames) if num_frames else 0 | 186 cpu_per_frame = (float(self.cpu_time) / num_frames) if num_frames else 0 |
| 181 results.Add(ThreadCpuTimeResultName(self.name), 'ms', cpu_per_frame) | 187 results.AddValue(scalar.ScalarValue( |
| 188 results.current_page, ThreadCpuTimeResultName(self.name), |
| 189 'ms', cpu_per_frame)) |
| 182 | 190 |
| 183 def AddDetailedResults(self, num_frames, results): | 191 def AddDetailedResults(self, num_frames, results): |
| 184 slices_by_category = collections.defaultdict(list) | 192 slices_by_category = collections.defaultdict(list) |
| 185 for s in self.all_slices: | 193 for s in self.all_slices: |
| 186 slices_by_category[s.category].append(s) | 194 slices_by_category[s.category].append(s) |
| 187 all_self_times = [] | 195 all_self_times = [] |
| 188 for category, slices_in_category in slices_by_category.iteritems(): | 196 for category, slices_in_category in slices_by_category.iteritems(): |
| 189 self_time = sum([x.self_time for x in slices_in_category]) | 197 self_time = sum([x.self_time for x in slices_in_category]) |
| 190 all_self_times.append(self_time) | 198 all_self_times.append(self_time) |
| 191 self_time_result = (float(self_time) / num_frames) if num_frames else 0 | 199 self_time_result = (float(self_time) / num_frames) if num_frames else 0 |
| 192 results.Add(ThreadDetailResultName(self.name, category), | 200 results.AddValue(scalar.ScalarValue( |
| 193 'ms', self_time_result) | 201 results.current_page, ThreadDetailResultName(self.name, category), |
| 202 'ms', self_time_result)) |
| 194 all_measured_time = sum(all_self_times) | 203 all_measured_time = sum(all_self_times) |
| 195 all_action_time = \ | 204 all_action_time = \ |
| 196 sum([record_range.bounds for record_range in self.record_ranges]) | 205 sum([record_range.bounds for record_range in self.record_ranges]) |
| 197 idle_time = max(0, all_action_time - all_measured_time) | 206 idle_time = max(0, all_action_time - all_measured_time) |
| 198 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 | 207 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 |
| 199 results.Add(ThreadDetailResultName(self.name, "idle"), | 208 results.AddValue(scalar.ScalarValue( |
| 200 'ms', idle_time_result) | 209 results.current_page, ThreadDetailResultName(self.name, "idle"), |
| 210 'ms', idle_time_result)) |
| 201 | 211 |
| 202 | 212 |
| 203 class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): | 213 class ThreadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric): |
| 204 def __init__(self): | 214 def __init__(self): |
| 205 super(ThreadTimesTimelineMetric, self).__init__() | 215 super(ThreadTimesTimelineMetric, self).__init__() |
| 206 # Minimal traces, for minimum noise in CPU-time measurements. | 216 # Minimal traces, for minimum noise in CPU-time measurements. |
| 207 self.results_to_report = AllThreads | 217 self.results_to_report = AllThreads |
| 208 self.details_to_report = NoThreads | 218 self.details_to_report = NoThreads |
| 209 | 219 |
| 210 def CountSlices(self, slices, substring): | 220 def CountSlices(self, slices, substring): |
| (...skipping 29 matching lines...) Expand all Loading... |
| 240 num_frames = self.CountSlices(frame_slices, FrameTraceName) | 250 num_frames = self.CountSlices(frame_slices, FrameTraceName) |
| 241 | 251 |
| 242 # Report the desired results and details. | 252 # Report the desired results and details. |
| 243 for thread_results in thread_category_results.values(): | 253 for thread_results in thread_category_results.values(): |
| 244 if thread_results.name in self.results_to_report: | 254 if thread_results.name in self.results_to_report: |
| 245 thread_results.AddResults(num_frames, results) | 255 thread_results.AddResults(num_frames, results) |
| 246 # TOOD(nduca): When generic results objects are done, this special case | 256 # TOOD(nduca): When generic results objects are done, this special case |
| 247 # can be replaced with a generic UI feature. | 257 # can be replaced with a generic UI feature. |
| 248 if thread_results.name in self.details_to_report: | 258 if thread_results.name in self.details_to_report: |
| 249 thread_results.AddDetailedResults(num_frames, results) | 259 thread_results.AddDetailedResults(num_frames, results) |
| OLD | NEW |