Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
|
petrcermak
2014/10/08 14:01:48
Again should be "2014".
Sami
2014/10/08 14:51:53
Ditto about the copyright year.
| |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 from telemetry.core.platform import tracing_category_filter | |
| 6 from telemetry.core.platform import tracing_options | |
| 7 from telemetry.timeline.model import TimelineModel | |
| 8 from telemetry.page import page_test | |
| 9 from telemetry.value import scalar | |
| 10 from telemetry.value import skip | |
| 11 | |
| 12 CATEGORIES = ['webkit.console', | |
|
Sami
2014/10/08 14:51:52
Assuming these constants aren't meant to be public
picksi1
2014/10/08 15:58:26
Done.
| |
| 13 'blink.console', | |
| 14 'benchmark', | |
| 15 'toplevel', | |
| 16 'blink', | |
| 17 'cc', | |
| 18 'v8'] | |
| 19 | |
| 20 TIME_OUT_IN_SECONDS = 60 | |
| 21 NUMBER_OF_RESULTS_TO_DISPLAY = 10 | |
| 22 | |
| 23 class TaskExecutionTime(page_test.PageTest): | |
| 24 | |
|
Sami
2014/10/08 14:51:53
I don't think we generally have blank lines betwee
| |
| 25 def __init__(self): | |
| 26 super(TaskExecutionTime, self).__init__('RunTaskExecutionTime') | |
|
Sami
2014/10/08 14:51:53
Why not reuse RunSmoothness for this?
picksi1
2014/10/08 15:58:27
I guess these are currently the same; I made a sep
| |
| 27 self._renderer_thread = None | |
| 28 | |
| 29 def WillNavigateToPage(self, page, tab): | |
| 30 | |
|
alexclarke
2014/10/08 13:28:28
nit: I assume we don't want blank lines after a fu
picksi1
2014/10/08 13:47:54
Yes, you're right. My eyes prefer it with spaces,
| |
| 31 category_filter = tracing_category_filter.TracingCategoryFilter() | |
| 32 | |
| 33 for category in CATEGORIES: | |
| 34 category_filter.AddIncludedCategory(category) | |
| 35 | |
| 36 options = tracing_options.TracingOptions() | |
| 37 options.enable_chrome_trace = True | |
| 38 | |
| 39 tab.browser.platform.tracing_controller.Start( | |
| 40 options, category_filter, TIME_OUT_IN_SECONDS) | |
|
Sami
2014/10/08 14:51:53
indent +2
| |
| 41 | |
| 42 | |
| 43 def DidRunActions(self, page, tab): | |
|
petrcermak
2014/10/08 14:01:48
Is there any reason for double blank lines around
picksi1
2014/10/08 15:01:38
I've removed the blank lines after the function de
| |
| 44 | |
| 45 timeline_data = tab.browser.platform.tracing_controller.Stop() | |
| 46 timeline_model = TimelineModel(timeline_data=timeline_data) | |
| 47 self._renderer_thread = timeline_model.GetRendererThreadFromTabId(tab.id) | |
| 48 | |
| 49 | |
| 50 def ValidateAndMeasurePage(self, page, tab, results): | |
| 51 | |
| 52 tasks = self.GetTasks(self._renderer_thread.parent) | |
| 53 | |
| 54 sorted_tasks = sorted(tasks, | |
| 55 key = lambda slice: slice.meanSelfDuration, reverse=True) | |
|
Sami
2014/10/08 14:51:53
nit: No spaces around "=" for named parameters.
picksi1
2014/10/08 15:58:27
Done.
| |
| 56 | |
| 57 # Tell summary code to not generate results for single pages as it makes | |
| 58 # the results page difficult to read | |
| 59 results.AddValue(skip.SkipValue.SetOnlyShowingSummaries(page)) | |
|
Sami
2014/10/08 14:51:52
Instead of this trick, could we just report the su
picksi1
2014/10/08 15:58:26
We can't accumulate values between separate execut
Sami
2014/10/09 10:28:13
The documentation for Value suggests that the page
picksi1
2014/10/09 13:02:20
As discussed offline, I'll look into a way to chan
| |
| 60 | |
| 61 max_tasks = min(NUMBER_OF_RESULTS_TO_DISPLAY, len(sorted_tasks)) | |
| 62 count = 0 | |
| 63 while count < max_tasks: | |
|
petrcermak
2014/10/08 14:01:48
"for count in xrange(max_tasks):" is more suited f
Sami
2014/10/08 14:51:53
nit: could also be written as:
for task in sort
picksi1
2014/10/08 15:01:38
Nice... Done!
picksi1
2014/10/08 15:58:27
Petr made this observation too. Done.
| |
| 64 task = sorted_tasks.pop(0) | |
|
petrcermak
2014/10/08 14:01:48
Popping from the beginning of a list is quite cost
picksi1
2014/10/08 15:01:38
Not needed any more with your earlier suggestion.
| |
| 65 results.AddValue(scalar.ScalarValue( | |
| 66 results.current_page, | |
| 67 task.key, | |
| 68 "ms", | |
|
Sami
2014/10/08 14:51:53
' instead of "
picksi1
2014/10/08 15:58:26
Done.
| |
| 69 task.meanSelfDuration, | |
| 70 description="Slowest tasks")) | |
|
Sami
2014/10/08 14:51:53
' instead of "
picksi1
2014/10/08 15:58:26
Done.
| |
| 71 count = count + 1 | |
| 72 | |
| 73 | |
| 74 def GetTasks(self, process): | |
|
Sami
2014/10/08 14:51:52
Does this need to be a member or could it be a fre
picksi1
2014/10/08 15:58:26
It could be free. Is it not best to encapsulate it
Sami
2014/10/09 10:28:14
Encapsulation is fine, but it could still be a @cl
| |
| 75 | |
| 76 task_dictionary = {} | |
| 77 | |
| 78 parent = 0 | |
| 79 depth = 1 | |
|
petrcermak
2014/10/08 14:01:48
depth is a constant (you don't change it anywhere
picksi1
2014/10/08 15:01:38
I made it a constant to give it a name, rather tha
| |
| 80 | |
| 81 for task_slice in process.IterAllSlicesOfName('MessageLoop::RunTask'): | |
|
petrcermak
2014/10/08 14:01:48
for parent, task_slice in enumerate(process.IterAl
| |
| 82 ProcessTasksForSlice(task_dictionary, task_slice, depth, parent) | |
| 83 parent = parent + 1 | |
| 84 | |
| 85 # Flatten dictionary into a list | |
| 86 tasks = [sliceData for key, sliceData in task_dictionary.items()] | |
|
petrcermak
2014/10/08 14:01:48
return task_dictionary.values()
Sami
2014/10/08 14:51:53
nit: Same as writing task_dictionary.values()
picksi1
2014/10/08 15:01:38
Done.
| |
| 87 | |
| 88 return tasks | |
| 89 | |
| 90 | |
| 91 class SliceData: | |
| 92 | |
| 93 def __init__(self, key, self_duration, total_duration, depth, parent): | |
| 94 | |
| 95 self.key = key | |
| 96 self.count = 1 | |
| 97 | |
| 98 self.sum_self_duration = self_duration | |
|
petrcermak
2014/10/08 14:01:48
Shouldn't there be some systematic order (e.g. sum
picksi1
2014/10/08 15:01:38
Good call. I've re-ordered them.
| |
| 99 self.sum_total_duration = total_duration | |
| 100 | |
| 101 self.min_self_duration = self_duration | |
| 102 self.max_self_duration = self_duration | |
| 103 self.min_total_duration = total_duration | |
| 104 self.max_total_duration = total_duration | |
| 105 | |
| 106 self.tree_location = [(depth, parent)] | |
| 107 | |
| 108 | |
| 109 def Update(self, self_duration, total_duration, depth, parent): | |
| 110 | |
| 111 self.count = self.count + 1 | |
|
petrcermak
2014/10/08 14:01:48
self.count += 1
| |
| 112 | |
| 113 self.sum_self_duration = (self.sum_self_duration + self_duration) | |
|
petrcermak
2014/10/08 14:01:48
Again, I would suggest using the += operator inste
picksi1
2014/10/08 15:01:38
Done.
| |
| 114 self.sum_total_duration = (self.sum_self_duration + total_duration) | |
| 115 | |
| 116 self.min_self_duration = min(self.min_self_duration, self_duration) | |
| 117 self.max_self_duration = max(self.max_self_duration, self_duration) | |
| 118 self.min_total_duration = min(self.min_total_duration, total_duration) | |
| 119 self.max_total_duration = max(self.max_total_duration, total_duration) | |
| 120 | |
| 121 self.tree_location.append( (depth, parent) ) | |
|
petrcermak
2014/10/08 14:01:48
Extra whitespace around the tuple.
Sami
2014/10/08 14:51:53
nit: no spaces outside the parens.
| |
| 122 | |
| 123 @property | |
| 124 def meanSelfDuration(self): | |
|
Sami
2014/10/08 14:51:52
mean_self_duration.
Do we want mean or median? Th
picksi1
2014/10/08 15:58:26
Done
| |
| 125 | |
| 126 if self.count == 0: | |
|
Sami
2014/10/08 14:51:53
If count starts at 1, does this ever happen?
picksi1
2014/10/08 15:58:26
Ha! You are correct... old habits die hard! This i
| |
| 127 return 0 | |
| 128 | |
| 129 return self.sum_self_duration / self.count | |
| 130 | |
| 131 | |
| 132 def ProcessTasksForSlice(dictionary, task_slice, depth, parent): | |
| 133 | |
| 134 # Deal with TRACE_EVENT_INSTANTs that have no duration | |
| 135 self_duration = task_slice.self_thread_time or 0.0 | |
| 136 total_duration = task_slice.thread_duration or 0.0 | |
| 137 | |
| 138 # There is at least one task that is tracked as both uppercase and lowercase, | |
| 139 # forcing the name to lowercase coalesces both. | |
| 140 key = task_slice.name.lower() | |
| 141 if key in dictionary: | |
| 142 dictionary[key].Update( | |
| 143 self_duration, total_duration, depth, parent) | |
| 144 else: | |
| 145 dictionary[key] = SliceData( | |
| 146 key, self_duration, total_duration, depth, parent) | |
| 147 | |
| 148 # Process sub slices recursively | |
| 149 for sub_slice in task_slice.sub_slices: | |
| 150 ProcessTasksForSlice(dictionary, sub_slice, depth+1, parent) | |
|
Sami
2014/10/08 14:51:53
nit: add spaces around the '+'
| |
| OLD | NEW |