Index: tools/perf/benchmarks/service_worker.py |
diff --git a/tools/perf/benchmarks/service_worker.py b/tools/perf/benchmarks/service_worker.py |
index 4a49666aff5ad1987ddf057cfce41928a8abe4f0..8db862f6300457e8b4fa51716125bf73aad28ff9 100644 |
--- a/tools/perf/benchmarks/service_worker.py |
+++ b/tools/perf/benchmarks/service_worker.py |
@@ -2,25 +2,117 @@ |
# Use of this source code is governed by a BSD-style license that can be |
# found in the LICENSE file. |
+import collections |
import page_sets |
+import re |
+ |
+from measurements import timeline_controller |
from telemetry import benchmark |
from telemetry.page import page_test |
+from telemetry.timeline import async_slice as async_slice_module |
+from telemetry.timeline import slice as slice_module |
from telemetry.value import scalar |
+class _ServiceWorkerTimelineMetric(object): |
+ def AddResultsOfCounters(self, process, counter_regex_string, results): |
+ counter_filter = re.compile(counter_regex_string) |
+ for counter_name, counter in process.counters.iteritems(): |
+ if not counter_filter.search(counter_name): |
+ continue |
+ |
+ total = sum(counter.totals) |
+ |
+ # Results objects cannot contain the '.' character, so remove that here. |
+ sanitized_counter_name = counter_name.replace('.', '_') |
+ |
+ results.AddValue(scalar.ScalarValue( |
+ results.current_page, sanitized_counter_name, 'count', total)) |
+ results.AddValue(scalar.ScalarValue( |
+ results.current_page, sanitized_counter_name + '_avg', 'count', |
+ total / float(len(counter.totals)))) |
+ |
+ def AddResultsOfEvents( |
+ self, process, thread_regex_string, event_regex_string, results): |
+ thread_filter = re.compile(thread_regex_string) |
+ event_filter = re.compile(event_regex_string) |
+ |
+ for thread in process.threads.itervalues(): |
+ thread_name = thread.name.replace('/', '_') |
+ if not thread_filter.search(thread_name): |
+ continue |
+ |
+ filtered_events = [] |
+ for event in thread.IterAllEvents(): |
+ event_name = event.name.replace('.', '_') |
+ if event_filter.search(event_name): |
+ filtered_events.append(event) |
+ |
+ async_events_by_name = collections.defaultdict(list) |
+ sync_events_by_name = collections.defaultdict(list) |
+ for event in filtered_events: |
+ if isinstance(event, async_slice_module.AsyncSlice): |
+ async_events_by_name[event.name].append(event) |
+ elif isinstance(event, slice_module.Slice): |
+ sync_events_by_name[event.name].append(event) |
+ |
+ for event_name, event_group in async_events_by_name.iteritems(): |
+ times = [e.duration for e in event_group] |
+ self._AddResultOfEvent(thread_name, event_name, times, results) |
+ |
+ for event_name, event_group in sync_events_by_name.iteritems(): |
+ times = [e.self_time for e in event_group] |
+ self._AddResultOfEvent(thread_name, event_name, times, results) |
+ |
+ def _AddResultOfEvent(self, thread_name, event_name, times, results): |
+ total = sum(times) |
+ biggest_jank = max(times) |
+ |
+ # Results objects cannot contain the '.' character, so remove that here. |
+ sanitized_event_name = event_name.replace('.', '_') |
+ |
+ full_name = thread_name + '|' + sanitized_event_name |
+ results.AddValue(scalar.ScalarValue( |
+ results.current_page, full_name, 'ms', total)) |
+ results.AddValue(scalar.ScalarValue( |
+ results.current_page, full_name + '_max', 'ms', biggest_jank)) |
+ results.AddValue(scalar.ScalarValue( |
+ results.current_page, full_name + '_avg', 'ms', total / len(times))) |
class _ServiceWorkerMeasurement(page_test.PageTest): |
+ def __init__(self, *args, **kwargs): |
+ super(_ServiceWorkerMeasurement, self).__init__(*args, **kwargs) |
+ self._timeline_controller = timeline_controller.TimelineController() |
+ |
def CustomizeBrowserOptions(self, options): |
options.AppendExtraBrowserArgs([ |
'--enable-experimental-web-platform-features' |
]) |
+ def WillNavigateToPage(self, page, tab): |
+ self._timeline_controller.SetUp(page, tab) |
+ self._timeline_controller.Start(tab) |
+ |
def ValidateAndMeasurePage(self, _, tab, results): |
tab.WaitForJavaScriptExpression('window.done', 40) |
+ self._timeline_controller.Stop(tab) |
+ |
+ # Measure JavaScript-land |
json = tab.EvaluateJavaScript('window.results') |
for key, value in json.iteritems(): |
results.AddValue(scalar.ScalarValue( |
results.current_page, key, value['units'], value['value'])) |
+ # Retrieve TRACE_EVENTs |
+ timeline_metric = _ServiceWorkerTimelineMetric() |
+ browser_process = self._timeline_controller.model.browser_process |
+ filter_text = '(RegisterServiceWorker|'\ |
+ 'UnregisterServiceWorker|'\ |
+ 'ProcessAllocate|'\ |
+ 'FindRegistrationForDocument|'\ |
+ 'PrepareForMainResource|'\ |
+ 'DispatchFetchEvent)' |
+ timeline_metric.AddResultsOfEvents( |
+ browser_process, 'IOThread', filter_text , results) |
@benchmark.Disabled |
class ServiceWorkerPerfTest(benchmark.Benchmark): |