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

Unified Diff: tools/perf/measurements/task_execution_time.py

Issue 636203002: Task Execution Duration metrics added as a new benchmark (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: tools/perf/measurements/task_execution_time.py
diff --git a/tools/perf/measurements/task_execution_time.py b/tools/perf/measurements/task_execution_time.py
new file mode 100644
index 0000000000000000000000000000000000000000..4914471436252636727928561b48a5781ce3fe3d
--- /dev/null
+++ b/tools/perf/measurements/task_execution_time.py
@@ -0,0 +1,150 @@
+# 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.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from telemetry.core.platform import tracing_category_filter
+from telemetry.core.platform import tracing_options
+from telemetry.timeline.model import TimelineModel
+from telemetry.page import page_test
+from telemetry.value import scalar
+from telemetry.value import skip
+
+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.
+ 'blink.console',
+ 'benchmark',
+ 'toplevel',
+ 'blink',
+ 'cc',
+ 'v8']
+
+TIME_OUT_IN_SECONDS = 60
+NUMBER_OF_RESULTS_TO_DISPLAY = 10
+
+class TaskExecutionTime(page_test.PageTest):
+
Sami 2014/10/08 14:51:53 I don't think we generally have blank lines betwee
+ def __init__(self):
+ 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
+ self._renderer_thread = None
+
+ def WillNavigateToPage(self, page, tab):
+
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,
+ category_filter = tracing_category_filter.TracingCategoryFilter()
+
+ for category in CATEGORIES:
+ category_filter.AddIncludedCategory(category)
+
+ options = tracing_options.TracingOptions()
+ options.enable_chrome_trace = True
+
+ tab.browser.platform.tracing_controller.Start(
+ options, category_filter, TIME_OUT_IN_SECONDS)
Sami 2014/10/08 14:51:53 indent +2
+
+
+ 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
+
+ timeline_data = tab.browser.platform.tracing_controller.Stop()
+ timeline_model = TimelineModel(timeline_data=timeline_data)
+ self._renderer_thread = timeline_model.GetRendererThreadFromTabId(tab.id)
+
+
+ def ValidateAndMeasurePage(self, page, tab, results):
+
+ tasks = self.GetTasks(self._renderer_thread.parent)
+
+ sorted_tasks = sorted(tasks,
+ 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.
+
+ # Tell summary code to not generate results for single pages as it makes
+ # the results page difficult to read
+ 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
+
+ max_tasks = min(NUMBER_OF_RESULTS_TO_DISPLAY, len(sorted_tasks))
+ count = 0
+ 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.
+ 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.
+ results.AddValue(scalar.ScalarValue(
+ results.current_page,
+ task.key,
+ "ms",
Sami 2014/10/08 14:51:53 ' instead of "
picksi1 2014/10/08 15:58:26 Done.
+ task.meanSelfDuration,
+ description="Slowest tasks"))
Sami 2014/10/08 14:51:53 ' instead of "
picksi1 2014/10/08 15:58:26 Done.
+ count = count + 1
+
+
+ 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
+
+ task_dictionary = {}
+
+ parent = 0
+ 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
+
+ for task_slice in process.IterAllSlicesOfName('MessageLoop::RunTask'):
petrcermak 2014/10/08 14:01:48 for parent, task_slice in enumerate(process.IterAl
+ ProcessTasksForSlice(task_dictionary, task_slice, depth, parent)
+ parent = parent + 1
+
+ # Flatten dictionary into a list
+ 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.
+
+ return tasks
+
+
+class SliceData:
+
+ def __init__(self, key, self_duration, total_duration, depth, parent):
+
+ self.key = key
+ self.count = 1
+
+ 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.
+ self.sum_total_duration = total_duration
+
+ self.min_self_duration = self_duration
+ self.max_self_duration = self_duration
+ self.min_total_duration = total_duration
+ self.max_total_duration = total_duration
+
+ self.tree_location = [(depth, parent)]
+
+
+ def Update(self, self_duration, total_duration, depth, parent):
+
+ self.count = self.count + 1
petrcermak 2014/10/08 14:01:48 self.count += 1
+
+ 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.
+ self.sum_total_duration = (self.sum_self_duration + total_duration)
+
+ self.min_self_duration = min(self.min_self_duration, self_duration)
+ self.max_self_duration = max(self.max_self_duration, self_duration)
+ self.min_total_duration = min(self.min_total_duration, total_duration)
+ self.max_total_duration = max(self.max_total_duration, total_duration)
+
+ 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.
+
+ @property
+ 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
+
+ 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
+ return 0
+
+ return self.sum_self_duration / self.count
+
+
+def ProcessTasksForSlice(dictionary, task_slice, depth, parent):
+
+ # Deal with TRACE_EVENT_INSTANTs that have no duration
+ self_duration = task_slice.self_thread_time or 0.0
+ total_duration = task_slice.thread_duration or 0.0
+
+ # There is at least one task that is tracked as both uppercase and lowercase,
+ # forcing the name to lowercase coalesces both.
+ key = task_slice.name.lower()
+ if key in dictionary:
+ dictionary[key].Update(
+ self_duration, total_duration, depth, parent)
+ else:
+ dictionary[key] = SliceData(
+ key, self_duration, total_duration, depth, parent)
+
+ # Process sub slices recursively
+ for sub_slice in task_slice.sub_slices:
+ ProcessTasksForSlice(dictionary, sub_slice, depth+1, parent)
Sami 2014/10/08 14:51:53 nit: add spaces around the '+'

Powered by Google App Engine
This is Rietveld 408576698