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 |