OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 |
| 5 """The page cycler benchmark. |
| 6 |
| 7 This benchmark registers a window load handler in which is forces a layout and |
| 8 then records the value of performance.now(). This call to now() measures the |
| 9 time from navigationStart (immediately after the previous page's beforeunload |
| 10 event) until after the layout in the page's load event. In addition, two garbage |
| 11 collections are performed in between the page loads (in the beforeunload event). |
| 12 This extra garbage collection time is not included in the benchmark times. |
| 13 |
| 14 Finally, various memory and IO statistics are gathered at the very end of |
| 15 cycling all pages. |
| 16 """ |
| 17 |
| 18 import os |
4 import sys | 19 import sys |
5 | 20 |
6 from perf_tools import histogram_measurement | 21 from perf_tools import histogram_measurement |
7 from telemetry.core import util | 22 from telemetry.core import util |
8 from telemetry.page import page_benchmark | 23 from telemetry.page import page_benchmark |
9 | 24 |
10 MEMORY_HISTOGRAMS = [ | 25 MEMORY_HISTOGRAMS = [ |
11 {'name': 'V8.MemoryExternalFragmentationTotal', 'units': 'percent'}, | 26 {'name': 'V8.MemoryExternalFragmentationTotal', 'units': 'percent'}, |
12 {'name': 'V8.MemoryHeapSampleTotalCommitted', 'units': 'kb'}, | 27 {'name': 'V8.MemoryHeapSampleTotalCommitted', 'units': 'kb'}, |
13 {'name': 'V8.MemoryHeapSampleTotalUsed', 'units': 'kb'}] | 28 {'name': 'V8.MemoryHeapSampleTotalUsed', 'units': 'kb'}] |
14 | 29 |
15 class PageCycler(page_benchmark.PageBenchmark): | 30 class PageCycler(page_benchmark.PageBenchmark): |
16 def WillNavigateToPage(self, page, tab): | 31 def AddCommandLineOptions(self, parser): |
| 32 # The page cyclers should default to 10 iterations. In order to change the |
| 33 # default of an option, we must remove and re-add it. |
| 34 pageset_repeat_option = parser.get_option('--pageset-repeat') |
| 35 pageset_repeat_option.default = 10 |
| 36 parser.remove_option('--pageset-repeat') |
| 37 parser.add_option(pageset_repeat_option) |
| 38 |
| 39 def WillRunPageSet(self, tab, results): |
| 40 # Avoid paying for a cross-renderer navigation on the first page on legacy |
| 41 # page cyclers which use the filesystem. |
| 42 if tab.browser.http_server: |
| 43 tab.Navigate(tab.browser.http_server.UrlOf('nonexistent.html')) |
| 44 |
| 45 with open(os.path.join(os.path.dirname(__file__), |
| 46 'page_cycler.js'), 'r') as f: |
| 47 self.page_cycler_js = f.read() # pylint: disable=W0201 |
| 48 |
17 # pylint: disable=W0201 | 49 # pylint: disable=W0201 |
18 self.start_commit_charge = tab.browser.memory_stats['SystemCommitCharge'] | 50 self.start_commit_charge = tab.browser.memory_stats['SystemCommitCharge'] |
19 | 51 |
20 def DidNavigateToPage(self, page, tab): | |
21 # pylint: disable=W0201 | 52 # pylint: disable=W0201 |
22 self.histograms = [histogram_measurement.HistogramMeasurement( | 53 self.histograms = [histogram_measurement.HistogramMeasurement( |
23 h, histogram_measurement.RENDERER_HISTOGRAM) | 54 h, histogram_measurement.RENDERER_HISTOGRAM) |
24 for h in MEMORY_HISTOGRAMS] | 55 for h in MEMORY_HISTOGRAMS] |
| 56 |
| 57 def WillNavigateToPage(self, page, tab): |
| 58 page.script_to_evaluate_on_commit = self.page_cycler_js |
| 59 |
| 60 def DidNavigateToPage(self, page, tab): |
25 for h in self.histograms: | 61 for h in self.histograms: |
26 h.Start(page, tab) | 62 h.Start(page, tab) |
27 | 63 |
28 def CustomizeBrowserOptions(self, options): | 64 def CustomizeBrowserOptions(self, options): |
29 options.AppendExtraBrowserArg('--dom-automation') | 65 options.AppendExtraBrowserArg('--dom-automation') |
30 options.AppendExtraBrowserArg('--js-flags=--expose_gc') | 66 options.AppendExtraBrowserArg('--js-flags=--expose_gc') |
31 options.AppendExtraBrowserArg('--no-sandbox') | 67 options.AppendExtraBrowserArg('--no-sandbox') |
32 # Temporarily enable threaded compositing on Mac on moz page set only. | 68 # Temporarily enable threaded compositing on Mac on moz page set only. |
33 # This malignancy is to diagnose an issue where the bots are experiencing | 69 # This malignancy is to diagnose an issue where the bots are experiencing |
34 # a regression that isn't reproducing locally. | 70 # a regression that isn't reproducing locally. |
(...skipping 10 matching lines...) Expand all Loading... |
45 memory = tab.browser.memory_stats | 81 memory = tab.browser.memory_stats |
46 if not memory['Browser']: | 82 if not memory['Browser']: |
47 return | 83 return |
48 | 84 |
49 metric = 'rss' | 85 metric = 'rss' |
50 if sys.platform == 'win32': | 86 if sys.platform == 'win32': |
51 metric = 'ws' | 87 metric = 'ws' |
52 | 88 |
53 # Browser | 89 # Browser |
54 if 'VM' in memory['Browser']: | 90 if 'VM' in memory['Browser']: |
55 results.Add('vm_size_f_b', 'bytes', memory['Browser']['VM'], | 91 results.AddSummary('vm_size_f_b', 'bytes', memory['Browser']['VM'], |
56 chart_name='vm_size_final_b', data_type='unimportant') | 92 chart_name='vm_size_final_b', data_type='unimportant') |
57 if 'VMPeak' in memory['Browser']: | 93 if 'VMPeak' in memory['Browser']: |
58 results.Add('vm_pk_b', 'bytes', memory['Browser']['VMPeak'], | 94 results.AddSummary('vm_pk_b', 'bytes', memory['Browser']['VMPeak'], |
59 chart_name='vm_peak_b', data_type='unimportant') | 95 chart_name='vm_peak_b', data_type='unimportant') |
60 if 'WorkingSetSize' in memory['Browser']: | 96 if 'WorkingSetSize' in memory['Browser']: |
61 results.Add('vm_%s_f_b' % metric, 'bytes', | 97 results.AddSummary('vm_%s_f_b' % metric, 'bytes', |
62 memory['Browser']['WorkingSetSize'], | 98 memory['Browser']['WorkingSetSize'], |
63 chart_name='vm_%s_final_b' % metric, data_type='unimportant') | 99 chart_name='vm_%s_final_b' % metric, |
| 100 data_type='unimportant') |
64 if 'WorkingSetSizePeak' in memory['Browser']: | 101 if 'WorkingSetSizePeak' in memory['Browser']: |
65 results.Add('%s_pk_b' % metric, 'bytes', | 102 results.AddSummary('%s_pk_b' % metric, 'bytes', |
66 memory['Browser']['WorkingSetSizePeak'], | 103 memory['Browser']['WorkingSetSizePeak'], |
67 chart_name='%s_peak_b' % metric, data_type='unimportant') | 104 chart_name='%s_peak_b' % metric, |
| 105 data_type='unimportant') |
68 if 'PrivateDirty' in memory['Browser']: | 106 if 'PrivateDirty' in memory['Browser']: |
69 results.Add('vm_private_dirty_f_b', 'bytes', | 107 results.AddSummary('vm_private_dirty_f_b', 'bytes', |
70 memory['Browser']['PrivateDirty'], | 108 memory['Browser']['PrivateDirty'], |
71 chart_name='vm_private_dirty_final_b', | 109 chart_name='vm_private_dirty_final_b', |
72 data_type='unimportant') | 110 data_type='unimportant') |
73 if 'ProportionalSetSize' in memory['Browser']: | 111 if 'ProportionalSetSize' in memory['Browser']: |
74 results.Add('vm_pss_f_b', 'bytes', | 112 results.AddSummary('vm_pss_f_b', 'bytes', |
75 memory['Browser']['ProportionalSetSize'], | 113 memory['Browser']['ProportionalSetSize'], |
76 chart_name='vm_pss_final_b', data_type='unimportant') | 114 chart_name='vm_pss_final_b', data_type='unimportant') |
77 | 115 |
78 # Renderer | 116 # Renderer |
79 if 'VM' in memory['Renderer']: | 117 if 'VM' in memory['Renderer']: |
80 results.Add('vm_size_f_r', 'bytes', memory['Renderer']['VM'], | 118 results.AddSummary('vm_size_f_r', 'bytes', memory['Renderer']['VM'], |
81 chart_name='vm_size_final_r', data_type='unimportant') | 119 chart_name='vm_size_final_r', data_type='unimportant') |
82 if 'VMPeak' in memory['Renderer']: | 120 if 'VMPeak' in memory['Renderer']: |
83 results.Add('vm_pk_r', 'bytes', memory['Browser']['VMPeak'], | 121 results.AddSummary('vm_pk_r', 'bytes', memory['Browser']['VMPeak'], |
84 chart_name='vm_peak_r', data_type='unimportant') | 122 chart_name='vm_peak_r', data_type='unimportant') |
85 if 'WorkingSetSize' in memory['Renderer']: | 123 if 'WorkingSetSize' in memory['Renderer']: |
86 results.Add('vm_%s_f_r' % metric, 'bytes', | 124 results.AddSummary('vm_%s_f_r' % metric, 'bytes', |
87 memory['Renderer']['WorkingSetSize'], | 125 memory['Renderer']['WorkingSetSize'], |
88 chart_name='vm_%s_final_r' % metric, data_type='unimportant') | 126 chart_name='vm_%s_final_r' % metric, |
| 127 data_type='unimportant') |
89 if 'WorkingSetSizePeak' in memory['Renderer']: | 128 if 'WorkingSetSizePeak' in memory['Renderer']: |
90 results.Add('%s_pk_r' % metric, 'bytes', | 129 results.AddSummary('%s_pk_r' % metric, 'bytes', |
91 memory['Browser']['WorkingSetSizePeak'], | 130 memory['Browser']['WorkingSetSizePeak'], |
92 chart_name='%s_peak_r' % metric, data_type='unimportant') | 131 chart_name='%s_peak_r' % metric, |
| 132 data_type='unimportant') |
93 if 'PrivateDirty' in memory['Renderer']: | 133 if 'PrivateDirty' in memory['Renderer']: |
94 results.Add('vm_private_dirty_f_r', 'bytes', | 134 results.AddSummary('vm_private_dirty_f_r', 'bytes', |
95 memory['Renderer']['PrivateDirty'], | 135 memory['Renderer']['PrivateDirty'], |
96 chart_name='vm_private_dirty_final_r', | 136 chart_name='vm_private_dirty_final_r', |
97 data_type='unimportant') | 137 data_type='unimportant') |
98 if 'ProportionalSetSize' in memory['Renderer']: | 138 if 'ProportionalSetSize' in memory['Renderer']: |
99 results.Add('vm_pss_f_r', 'bytes', | 139 results.AddSummary('vm_pss_f_r', 'bytes', |
100 memory['Renderer']['ProportionalSetSize'], | 140 memory['Renderer']['ProportionalSetSize'], |
101 chart_name='vm_pss_final_r', data_type='unimportant') | 141 chart_name='vm_pss_final_r', data_type='unimportant') |
102 | 142 |
103 # Total | 143 # Total |
104 if 'VM' in memory['Browser'] and 'VM' in memory['Renderer']: | 144 if 'VM' in memory['Browser'] and 'VM' in memory['Renderer']: |
105 results.Add('vm_size_f_t', 'bytes', | 145 results.AddSummary('vm_size_f_t', 'bytes', |
106 memory['Browser']['VM'] + memory['Renderer']['VM'], | 146 memory['Browser']['VM'] + memory['Renderer']['VM'], |
107 chart_name='vm_size_final_t', data_type='unimportant') | 147 chart_name='vm_size_final_t', data_type='unimportant') |
108 if ('WorkingSetSize' in memory['Browser'] and | 148 if ('WorkingSetSize' in memory['Browser'] and |
109 'WorkingSetSize' in memory['Renderer']): | 149 'WorkingSetSize' in memory['Renderer']): |
110 results.Add('vm_%s_f_t' % metric, 'bytes', | 150 results.AddSummary('vm_%s_f_t' % metric, 'bytes', |
111 memory['Browser']['WorkingSetSize'] + | 151 memory['Browser']['WorkingSetSize'] + |
112 memory['Renderer']['WorkingSetSize'], | 152 memory['Renderer']['WorkingSetSize'], |
113 chart_name='vm_%s_final_t' % metric, data_type='unimportant') | 153 chart_name='vm_%s_final_t' % metric, |
| 154 data_type='unimportant') |
114 if ('PrivateDirty' in memory['Browser'] and | 155 if ('PrivateDirty' in memory['Browser'] and |
115 'PrivateDirty' in memory['Renderer']): | 156 'PrivateDirty' in memory['Renderer']): |
116 results.Add('vm_private_dirty_f_t', 'bytes', | 157 results.AddSummary('vm_private_dirty_f_t', 'bytes', |
117 memory['Browser']['PrivateDirty'] + | 158 memory['Browser']['PrivateDirty'] + |
118 memory['Renderer']['PrivateDirty'], | 159 memory['Renderer']['PrivateDirty'], |
119 chart_name='vm_private_dirty_final_t', | 160 chart_name='vm_private_dirty_final_t', |
120 data_type='unimportant') | 161 data_type='unimportant') |
121 if ('ProportionalSetSize' in memory['Browser'] and | 162 if ('ProportionalSetSize' in memory['Browser'] and |
122 'ProportionalSetSize' in memory['Renderer']): | 163 'ProportionalSetSize' in memory['Renderer']): |
123 results.Add('vm_pss_f_t', 'bytes', | 164 results.AddSummary('vm_pss_f_t', 'bytes', |
124 memory['Browser']['ProportionalSetSize'] + | 165 memory['Browser']['ProportionalSetSize'] + |
125 memory['Renderer']['ProportionalSetSize'], | 166 memory['Renderer']['ProportionalSetSize'], |
126 chart_name='vm_pss_final_t', data_type='unimportant') | 167 chart_name='vm_pss_final_t', data_type='unimportant') |
127 | 168 |
128 results.Add('cc', 'kb', | 169 results.AddSummary('cc', 'kb', |
129 memory['SystemCommitCharge'] - self.start_commit_charge, | 170 memory['SystemCommitCharge'] - self.start_commit_charge, |
130 chart_name='commit_charge', data_type='unimportant') | 171 chart_name='commit_charge', data_type='unimportant') |
131 results.Add('proc_', 'count', memory['ProcessCount'], | 172 results.AddSummary('proc_', 'count', memory['ProcessCount'], |
132 chart_name='processes', data_type='unimportant') | 173 chart_name='processes', data_type='unimportant') |
133 | 174 |
134 def MeasureIO(self, tab, results): | 175 def MeasureIO(self, tab, results): |
135 io_stats = tab.browser.io_stats | 176 io_stats = tab.browser.io_stats |
136 if not io_stats['Browser']: | 177 if not io_stats['Browser']: |
137 return | 178 return |
138 results.Add('r_op_b', '', io_stats['Browser']['ReadOperationCount'], | 179 results.AddSummary('r_op_b', '', io_stats['Browser']['ReadOperationCount'], |
139 chart_name='read_op_b', data_type='unimportant') | 180 chart_name='read_op_b', data_type='unimportant') |
140 results.Add('w_op_b', '', io_stats['Browser']['WriteOperationCount'], | 181 results.AddSummary('w_op_b', '', io_stats['Browser']['WriteOperationCount'], |
141 chart_name='write_op_b', data_type='unimportant') | 182 chart_name='write_op_b', data_type='unimportant') |
142 results.Add('r_b', 'kb', io_stats['Browser']['ReadTransferCount'] / 1024, | 183 results.AddSummary('r_b', 'kb', |
143 chart_name='read_byte_b', data_type='unimportant') | 184 io_stats['Browser']['ReadTransferCount'] / 1024, |
144 results.Add('w_b', 'kb', io_stats['Browser']['WriteTransferCount'] / 1024, | 185 chart_name='read_byte_b', data_type='unimportant') |
145 chart_name='write_byte_b', data_type='unimportant') | 186 results.AddSummary('w_b', 'kb', |
146 results.Add('r_op_r', '', io_stats['Renderer']['ReadOperationCount'], | 187 io_stats['Browser']['WriteTransferCount'] / 1024, |
147 chart_name='read_op_r', data_type='unimportant') | 188 chart_name='write_byte_b', data_type='unimportant') |
148 results.Add('w_op_r', '', io_stats['Renderer']['WriteOperationCount'], | 189 results.AddSummary('r_op_r', '', io_stats['Renderer']['ReadOperationCount'], |
149 chart_name='write_op_r', data_type='unimportant') | 190 chart_name='read_op_r', data_type='unimportant') |
150 results.Add('r_r', 'kb', io_stats['Renderer']['ReadTransferCount'] / 1024, | 191 results.AddSummary('w_op_r', '', |
151 chart_name='read_byte_r', data_type='unimportant') | 192 io_stats['Renderer']['WriteOperationCount'], |
152 results.Add('w_r', 'kb', io_stats['Renderer']['WriteTransferCount'] / 1024, | 193 chart_name='write_op_r', data_type='unimportant') |
153 chart_name='write_byte_r', data_type='unimportant') | 194 results.AddSummary('r_r', 'kb', |
| 195 io_stats['Renderer']['ReadTransferCount'] / 1024, |
| 196 chart_name='read_byte_r', data_type='unimportant') |
| 197 results.AddSummary('w_r', 'kb', |
| 198 io_stats['Renderer']['WriteTransferCount'] / 1024, |
| 199 chart_name='write_byte_r', data_type='unimportant') |
154 | 200 |
155 def MeasurePage(self, page, tab, results): | 201 def MeasurePage(self, page, tab, results): |
156 def _IsDone(): | 202 def _IsDone(): |
157 return tab.GetCookieByName('__pc_done') == '1' | 203 return bool(tab.GetCookieByName('__pc_load_time')) |
158 util.WaitFor(_IsDone, 1200, poll_interval=5) | 204 util.WaitFor(_IsDone, 1200) |
159 print 'Pages: [%s]' % tab.GetCookieByName('__pc_pages') | |
160 | |
161 self.MeasureMemory(tab, results) | |
162 self.MeasureIO(tab, results) | |
163 | 205 |
164 for h in self.histograms: | 206 for h in self.histograms: |
165 h.GetValue(page, tab, results) | 207 h.GetValue(page, tab, results) |
166 | 208 |
167 def _IsNavigatedToReport(): | 209 results.Add('t', 'ms', int(float(tab.GetCookieByName('__pc_load_time'))), |
168 return tab.GetCookieByName('__navigated_to_report') == '1' | 210 chart_name='times') |
169 util.WaitFor(_IsNavigatedToReport, 60, poll_interval=5) | 211 |
170 timings = tab.EvaluateJavaScript('__get_timings()').split(',') | 212 def DidRunPageSet(self, tab, results): |
171 results.Add('t', 'ms', [int(t) for t in timings], chart_name='times') | 213 self.MeasureMemory(tab, results) |
| 214 self.MeasureIO(tab, results) |
OLD | NEW |