Chromium Code Reviews| Index: tools/telemetry/telemetry/web_perf/metrics/blob_timeline.py |
| diff --git a/tools/telemetry/telemetry/web_perf/metrics/blob_timeline.py b/tools/telemetry/telemetry/web_perf/metrics/blob_timeline.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9c962cc91518522dadd442f8056f7903ad789634 |
| --- /dev/null |
| +++ b/tools/telemetry/telemetry/web_perf/metrics/blob_timeline.py |
| @@ -0,0 +1,104 @@ |
| +# Copyryight 2015 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import sys |
| + |
| +from telemetry.value import list_of_scalar_values |
| +from telemetry.web_perf.metrics import timeline_based_metric |
| + |
|
eakuefner
2015/05/22 18:33:18
nit: two newlines between top-level definitions.
dmurph
2015/05/22 19:06:20
Done.
|
| +class BlobTimelineMetric(timeline_based_metric.TimelineBasedMetric): |
| + """ |
| + Reports |
| + * blob write time in the Action_CreateBlob interaction |
| + * blob read time in the Action_ReadBlobs interaction |
| + * BlobCreateAndRead interaction length, for measuring total time |
| + to write and then read a blob. |
| + """ |
|
eakuefner
2015/05/22 18:33:18
nit: extra newline after docstring. also, can you
dmurph
2015/05/22 19:06:20
Done.
|
| + WRITE_INTERACTION_LABEL = 'Action_CreateBlob' |
|
eakuefner
2015/05/22 18:33:18
Please move these constants above, out of the clas
dmurph
2015/05/22 19:06:20
Done, and made the predicates class methods
|
| + WRITE_EVENT_NAME = 'Registry::RegisterBlob' |
| + READ_INTERACTION_LABEL = 'Action_ReadBlobs' |
| + READ_EVENT_NAME = 'BlobRequest' |
| + WRITE_READ_INTERACTION_LABEL = 'BlobCreateAndRead' |
| + |
| + def __init__(self): |
| + super(BlobTimelineMetric, self).__init__() |
| + |
| + def _WriteEventPredicate(self, event): |
| + return event.name == self.WRITE_EVENT_NAME |
| + |
| + def _ReadEventPredicate(self, event): |
| + return event.name == self.READ_EVENT_NAME |
| + |
| + def AddResults(self, model, renderer_thread, interactions, results): |
| + assert interactions |
| + |
| + browser_process = \ |
|
eakuefner
2015/05/22 18:33:19
nit: backslash 1. should not be necessary here si
dmurph
2015/05/22 19:06:20
Done.
|
| + [p for p in model.GetAllProcesses() if p.name == "Browser"][0] |
| + |
| + write_events = [] |
| + read_events = [] |
| + for event in renderer_thread.parent.IterAllEvents( |
| + event_predicate=self._WriteEventPredicate): |
|
eakuefner
2015/05/22 18:33:19
I don't think this is going to work: event_predica
dmurph
2015/05/22 19:06:20
I changed them to class methods, does that work be
|
| + write_events.append(event) |
| + for event in browser_process.parent.IterAllEvents( |
| + event_predicate=self._ReadEventPredicate): |
| + read_events.append(event) |
| + |
| + self._AddWriteResultsInternal(write_events, interactions, results) |
| + self._AddReadResultsInternal(read_events, interactions, results) |
| + |
| + def _AddWriteResultsInternal(self, events, interactions, results): |
| + writes = [] |
| + write_then_reads = [] |
| + |
| + for interaction in interactions: |
| + if interaction.label == self.WRITE_READ_INTERACTION_LABEL: |
| + write_then_reads.append(interaction.end - interaction.start) |
| + continue |
| + elif interaction.label != self.WRITE_INTERACTION_LABEL: |
| + continue |
| + for duration in [(e.end - e.start) for e in events |
| + if (interaction.start <= e.start <= interaction.end) and |
| + self._WriteEventPredicate(e)]: |
| + writes.append(duration) |
| + |
| + if writes: |
| + results.AddValue(list_of_scalar_values.ListOfScalarValues( |
| + page=results.current_page, |
| + name='blob_writes', |
| + units='ms', |
| + values=writes, |
| + description=('List of durations of blob writes.'))) |
| + if write_then_reads: |
| + results.AddValue(list_of_scalar_values.ListOfScalarValues( |
| + page=results.current_page, |
| + name='blob_write_reads', |
| + units='ms', |
| + values=write_then_reads, |
| + description=('List of times for blob creation then read.'))) |
| + |
| + |
| + def _AddReadResultsInternal(self, events, interactions, results): |
| + reads = [] |
| + |
| + for interaction in interactions: |
| + if interaction.label != self.READ_INTERACTION_LABEL: |
| + continue |
| + min_read_start = sys.maxint |
| + max_read_end = -sys.maxint - 1 |
| + for event in [e for e in events \ |
|
eakuefner
2015/05/22 18:33:19
no backslash here either
dmurph
2015/05/22 19:06:20
Done.
|
| + if (interaction.start <= e.start <= interaction.end) and |
| + self._ReadEventPredicate(e)]: |
| + min_read_start = min(event.start, min_read_start) |
| + max_read_end = max(event.end, max_read_end) |
| + if min_read_start != sys.maxint: |
| + reads.append(max_read_end - min_read_start) |
| + |
| + if reads: |
| + results.AddValue(list_of_scalar_values.ListOfScalarValues( |
| + page=results.current_page, |
| + name='blob_reads', |
| + units='ms', |
| + values=reads, |
| + description=('List of durations of blob part reads (not whole blob)'))) |