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 | |
19 import sys | 4 import sys |
20 | 5 |
21 from perf_tools import histogram_measurement | 6 from perf_tools import histogram_measurement |
22 from telemetry.core import util | 7 from telemetry.core import util |
23 from telemetry.page import page_benchmark | 8 from telemetry.page import page_benchmark |
24 | 9 |
25 MEMORY_HISTOGRAMS = [ | 10 MEMORY_HISTOGRAMS = [ |
26 {'name': 'V8.MemoryExternalFragmentationTotal', 'units': 'percent'}, | 11 {'name': 'V8.MemoryExternalFragmentationTotal', 'units': 'percent'}, |
27 {'name': 'V8.MemoryHeapSampleTotalCommitted', 'units': 'kb'}, | 12 {'name': 'V8.MemoryHeapSampleTotalCommitted', 'units': 'kb'}, |
28 {'name': 'V8.MemoryHeapSampleTotalUsed', 'units': 'kb'}] | 13 {'name': 'V8.MemoryHeapSampleTotalUsed', 'units': 'kb'}] |
29 | 14 |
30 class PageCycler(page_benchmark.PageBenchmark): | 15 class PageCycler(page_benchmark.PageBenchmark): |
31 def AddCommandLineOptions(self, parser): | 16 def WillNavigateToPage(self, page, tab): |
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 | |
49 # pylint: disable=W0201 | 17 # pylint: disable=W0201 |
50 self.start_commit_charge = tab.browser.memory_stats['SystemCommitCharge'] | 18 self.start_commit_charge = tab.browser.memory_stats['SystemCommitCharge'] |
51 | 19 |
| 20 def DidNavigateToPage(self, page, tab): |
52 # pylint: disable=W0201 | 21 # pylint: disable=W0201 |
53 self.histograms = [histogram_measurement.HistogramMeasurement( | 22 self.histograms = [histogram_measurement.HistogramMeasurement( |
54 h, histogram_measurement.RENDERER_HISTOGRAM) | 23 h, histogram_measurement.RENDERER_HISTOGRAM) |
55 for h in MEMORY_HISTOGRAMS] | 24 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): | |
61 for h in self.histograms: | 25 for h in self.histograms: |
62 h.Start(page, tab) | 26 h.Start(page, tab) |
63 | 27 |
64 def CustomizeBrowserOptions(self, options): | 28 def CustomizeBrowserOptions(self, options): |
65 options.AppendExtraBrowserArg('--dom-automation') | 29 options.AppendExtraBrowserArg('--dom-automation') |
66 options.AppendExtraBrowserArg('--js-flags=--expose_gc') | 30 options.AppendExtraBrowserArg('--js-flags=--expose_gc') |
67 options.AppendExtraBrowserArg('--no-sandbox') | 31 options.AppendExtraBrowserArg('--no-sandbox') |
68 # Temporarily enable threaded compositing on Mac on moz page set only. | 32 # Temporarily enable threaded compositing on Mac on moz page set only. |
69 # This malignancy is to diagnose an issue where the bots are experiencing | 33 # This malignancy is to diagnose an issue where the bots are experiencing |
70 # a regression that isn't reproducing locally. | 34 # a regression that isn't reproducing locally. |
(...skipping 10 matching lines...) Expand all Loading... |
81 memory = tab.browser.memory_stats | 45 memory = tab.browser.memory_stats |
82 if not memory['Browser']: | 46 if not memory['Browser']: |
83 return | 47 return |
84 | 48 |
85 metric = 'rss' | 49 metric = 'rss' |
86 if sys.platform == 'win32': | 50 if sys.platform == 'win32': |
87 metric = 'ws' | 51 metric = 'ws' |
88 | 52 |
89 # Browser | 53 # Browser |
90 if 'VM' in memory['Browser']: | 54 if 'VM' in memory['Browser']: |
91 results.AddSummary('vm_size_f_b', 'bytes', memory['Browser']['VM'], | 55 results.Add('vm_size_f_b', 'bytes', memory['Browser']['VM'], |
92 chart_name='vm_size_final_b', data_type='unimportant') | 56 chart_name='vm_size_final_b', data_type='unimportant') |
93 if 'VMPeak' in memory['Browser']: | 57 if 'VMPeak' in memory['Browser']: |
94 results.AddSummary('vm_pk_b', 'bytes', memory['Browser']['VMPeak'], | 58 results.Add('vm_pk_b', 'bytes', memory['Browser']['VMPeak'], |
95 chart_name='vm_peak_b', data_type='unimportant') | 59 chart_name='vm_peak_b', data_type='unimportant') |
96 if 'WorkingSetSize' in memory['Browser']: | 60 if 'WorkingSetSize' in memory['Browser']: |
97 results.AddSummary('vm_%s_f_b' % metric, 'bytes', | 61 results.Add('vm_%s_f_b' % metric, 'bytes', |
98 memory['Browser']['WorkingSetSize'], | 62 memory['Browser']['WorkingSetSize'], |
99 chart_name='vm_%s_final_b' % metric, | 63 chart_name='vm_%s_final_b' % metric, data_type='unimportant') |
100 data_type='unimportant') | |
101 if 'WorkingSetSizePeak' in memory['Browser']: | 64 if 'WorkingSetSizePeak' in memory['Browser']: |
102 results.AddSummary('%s_pk_b' % metric, 'bytes', | 65 results.Add('%s_pk_b' % metric, 'bytes', |
103 memory['Browser']['WorkingSetSizePeak'], | 66 memory['Browser']['WorkingSetSizePeak'], |
104 chart_name='%s_peak_b' % metric, | 67 chart_name='%s_peak_b' % metric, data_type='unimportant') |
105 data_type='unimportant') | |
106 if 'PrivateDirty' in memory['Browser']: | 68 if 'PrivateDirty' in memory['Browser']: |
107 results.AddSummary('vm_private_dirty_f_b', 'bytes', | 69 results.Add('vm_private_dirty_f_b', 'bytes', |
108 memory['Browser']['PrivateDirty'], | 70 memory['Browser']['PrivateDirty'], |
109 chart_name='vm_private_dirty_final_b', | 71 chart_name='vm_private_dirty_final_b', |
110 data_type='unimportant') | 72 data_type='unimportant') |
111 if 'ProportionalSetSize' in memory['Browser']: | 73 if 'ProportionalSetSize' in memory['Browser']: |
112 results.AddSummary('vm_pss_f_b', 'bytes', | 74 results.Add('vm_pss_f_b', 'bytes', |
113 memory['Browser']['ProportionalSetSize'], | 75 memory['Browser']['ProportionalSetSize'], |
114 chart_name='vm_pss_final_b', data_type='unimportant') | 76 chart_name='vm_pss_final_b', data_type='unimportant') |
115 | 77 |
116 # Renderer | 78 # Renderer |
117 if 'VM' in memory['Renderer']: | 79 if 'VM' in memory['Renderer']: |
118 results.AddSummary('vm_size_f_r', 'bytes', memory['Renderer']['VM'], | 80 results.Add('vm_size_f_r', 'bytes', memory['Renderer']['VM'], |
119 chart_name='vm_size_final_r', data_type='unimportant') | 81 chart_name='vm_size_final_r', data_type='unimportant') |
120 if 'VMPeak' in memory['Renderer']: | 82 if 'VMPeak' in memory['Renderer']: |
121 results.AddSummary('vm_pk_r', 'bytes', memory['Browser']['VMPeak'], | 83 results.Add('vm_pk_r', 'bytes', memory['Browser']['VMPeak'], |
122 chart_name='vm_peak_r', data_type='unimportant') | 84 chart_name='vm_peak_r', data_type='unimportant') |
123 if 'WorkingSetSize' in memory['Renderer']: | 85 if 'WorkingSetSize' in memory['Renderer']: |
124 results.AddSummary('vm_%s_f_r' % metric, 'bytes', | 86 results.Add('vm_%s_f_r' % metric, 'bytes', |
125 memory['Renderer']['WorkingSetSize'], | 87 memory['Renderer']['WorkingSetSize'], |
126 chart_name='vm_%s_final_r' % metric, | 88 chart_name='vm_%s_final_r' % metric, data_type='unimportant') |
127 data_type='unimportant') | |
128 if 'WorkingSetSizePeak' in memory['Renderer']: | 89 if 'WorkingSetSizePeak' in memory['Renderer']: |
129 results.AddSummary('%s_pk_r' % metric, 'bytes', | 90 results.Add('%s_pk_r' % metric, 'bytes', |
130 memory['Browser']['WorkingSetSizePeak'], | 91 memory['Browser']['WorkingSetSizePeak'], |
131 chart_name='%s_peak_r' % metric, | 92 chart_name='%s_peak_r' % metric, data_type='unimportant') |
132 data_type='unimportant') | |
133 if 'PrivateDirty' in memory['Renderer']: | 93 if 'PrivateDirty' in memory['Renderer']: |
134 results.AddSummary('vm_private_dirty_f_r', 'bytes', | 94 results.Add('vm_private_dirty_f_r', 'bytes', |
135 memory['Renderer']['PrivateDirty'], | 95 memory['Renderer']['PrivateDirty'], |
136 chart_name='vm_private_dirty_final_r', | 96 chart_name='vm_private_dirty_final_r', |
137 data_type='unimportant') | 97 data_type='unimportant') |
138 if 'ProportionalSetSize' in memory['Renderer']: | 98 if 'ProportionalSetSize' in memory['Renderer']: |
139 results.AddSummary('vm_pss_f_r', 'bytes', | 99 results.Add('vm_pss_f_r', 'bytes', |
140 memory['Renderer']['ProportionalSetSize'], | 100 memory['Renderer']['ProportionalSetSize'], |
141 chart_name='vm_pss_final_r', data_type='unimportant') | 101 chart_name='vm_pss_final_r', data_type='unimportant') |
142 | 102 |
143 # Total | 103 # Total |
144 if 'VM' in memory['Browser'] and 'VM' in memory['Renderer']: | 104 if 'VM' in memory['Browser'] and 'VM' in memory['Renderer']: |
145 results.AddSummary('vm_size_f_t', 'bytes', | 105 results.Add('vm_size_f_t', 'bytes', |
146 memory['Browser']['VM'] + memory['Renderer']['VM'], | 106 memory['Browser']['VM'] + memory['Renderer']['VM'], |
147 chart_name='vm_size_final_t', data_type='unimportant') | 107 chart_name='vm_size_final_t', data_type='unimportant') |
148 if ('WorkingSetSize' in memory['Browser'] and | 108 if ('WorkingSetSize' in memory['Browser'] and |
149 'WorkingSetSize' in memory['Renderer']): | 109 'WorkingSetSize' in memory['Renderer']): |
150 results.AddSummary('vm_%s_f_t' % metric, 'bytes', | 110 results.Add('vm_%s_f_t' % metric, 'bytes', |
151 memory['Browser']['WorkingSetSize'] + | 111 memory['Browser']['WorkingSetSize'] + |
152 memory['Renderer']['WorkingSetSize'], | 112 memory['Renderer']['WorkingSetSize'], |
153 chart_name='vm_%s_final_t' % metric, | 113 chart_name='vm_%s_final_t' % metric, data_type='unimportant') |
154 data_type='unimportant') | |
155 if ('PrivateDirty' in memory['Browser'] and | 114 if ('PrivateDirty' in memory['Browser'] and |
156 'PrivateDirty' in memory['Renderer']): | 115 'PrivateDirty' in memory['Renderer']): |
157 results.AddSummary('vm_private_dirty_f_t', 'bytes', | 116 results.Add('vm_private_dirty_f_t', 'bytes', |
158 memory['Browser']['PrivateDirty'] + | 117 memory['Browser']['PrivateDirty'] + |
159 memory['Renderer']['PrivateDirty'], | 118 memory['Renderer']['PrivateDirty'], |
160 chart_name='vm_private_dirty_final_t', | 119 chart_name='vm_private_dirty_final_t', |
161 data_type='unimportant') | 120 data_type='unimportant') |
162 if ('ProportionalSetSize' in memory['Browser'] and | 121 if ('ProportionalSetSize' in memory['Browser'] and |
163 'ProportionalSetSize' in memory['Renderer']): | 122 'ProportionalSetSize' in memory['Renderer']): |
164 results.AddSummary('vm_pss_f_t', 'bytes', | 123 results.Add('vm_pss_f_t', 'bytes', |
165 memory['Browser']['ProportionalSetSize'] + | 124 memory['Browser']['ProportionalSetSize'] + |
166 memory['Renderer']['ProportionalSetSize'], | 125 memory['Renderer']['ProportionalSetSize'], |
167 chart_name='vm_pss_final_t', data_type='unimportant') | 126 chart_name='vm_pss_final_t', data_type='unimportant') |
168 | 127 |
169 results.AddSummary('cc', 'kb', | 128 results.Add('cc', 'kb', |
170 memory['SystemCommitCharge'] - self.start_commit_charge, | 129 memory['SystemCommitCharge'] - self.start_commit_charge, |
171 chart_name='commit_charge', data_type='unimportant') | 130 chart_name='commit_charge', data_type='unimportant') |
172 results.AddSummary('proc_', 'count', memory['ProcessCount'], | 131 results.Add('proc_', 'count', memory['ProcessCount'], |
173 chart_name='processes', data_type='unimportant') | 132 chart_name='processes', data_type='unimportant') |
174 | 133 |
175 def MeasureIO(self, tab, results): | 134 def MeasureIO(self, tab, results): |
176 io_stats = tab.browser.io_stats | 135 io_stats = tab.browser.io_stats |
177 if not io_stats['Browser']: | 136 if not io_stats['Browser']: |
178 return | 137 return |
179 results.AddSummary('r_op_b', '', io_stats['Browser']['ReadOperationCount'], | 138 results.Add('r_op_b', '', io_stats['Browser']['ReadOperationCount'], |
180 chart_name='read_op_b', data_type='unimportant') | 139 chart_name='read_op_b', data_type='unimportant') |
181 results.AddSummary('w_op_b', '', io_stats['Browser']['WriteOperationCount'], | 140 results.Add('w_op_b', '', io_stats['Browser']['WriteOperationCount'], |
182 chart_name='write_op_b', data_type='unimportant') | 141 chart_name='write_op_b', data_type='unimportant') |
183 results.AddSummary('r_b', 'kb', | 142 results.Add('r_b', 'kb', io_stats['Browser']['ReadTransferCount'] / 1024, |
184 io_stats['Browser']['ReadTransferCount'] / 1024, | 143 chart_name='read_byte_b', data_type='unimportant') |
185 chart_name='read_byte_b', data_type='unimportant') | 144 results.Add('w_b', 'kb', io_stats['Browser']['WriteTransferCount'] / 1024, |
186 results.AddSummary('w_b', 'kb', | 145 chart_name='write_byte_b', data_type='unimportant') |
187 io_stats['Browser']['WriteTransferCount'] / 1024, | 146 results.Add('r_op_r', '', io_stats['Renderer']['ReadOperationCount'], |
188 chart_name='write_byte_b', data_type='unimportant') | 147 chart_name='read_op_r', data_type='unimportant') |
189 results.AddSummary('r_op_r', '', io_stats['Renderer']['ReadOperationCount'], | 148 results.Add('w_op_r', '', io_stats['Renderer']['WriteOperationCount'], |
190 chart_name='read_op_r', data_type='unimportant') | 149 chart_name='write_op_r', data_type='unimportant') |
191 results.AddSummary('w_op_r', '', | 150 results.Add('r_r', 'kb', io_stats['Renderer']['ReadTransferCount'] / 1024, |
192 io_stats['Renderer']['WriteOperationCount'], | 151 chart_name='read_byte_r', data_type='unimportant') |
193 chart_name='write_op_r', data_type='unimportant') | 152 results.Add('w_r', 'kb', io_stats['Renderer']['WriteTransferCount'] / 1024, |
194 results.AddSummary('r_r', 'kb', | 153 chart_name='write_byte_r', data_type='unimportant') |
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') | |
200 | 154 |
201 def MeasurePage(self, page, tab, results): | 155 def MeasurePage(self, page, tab, results): |
202 def _IsDone(): | 156 def _IsDone(): |
203 return bool(tab.GetCookieByName('__pc_load_time')) | 157 return tab.GetCookieByName('__pc_done') == '1' |
204 util.WaitFor(_IsDone, 1200) | 158 util.WaitFor(_IsDone, 1200, poll_interval=5) |
| 159 print 'Pages: [%s]' % tab.GetCookieByName('__pc_pages') |
| 160 |
| 161 self.MeasureMemory(tab, results) |
| 162 self.MeasureIO(tab, results) |
205 | 163 |
206 for h in self.histograms: | 164 for h in self.histograms: |
207 h.GetValue(page, tab, results) | 165 h.GetValue(page, tab, results) |
208 | 166 |
209 results.Add('t', 'ms', int(float(tab.GetCookieByName('__pc_load_time'))), | 167 def _IsNavigatedToReport(): |
210 chart_name='times') | 168 return tab.GetCookieByName('__navigated_to_report') == '1' |
211 | 169 util.WaitFor(_IsNavigatedToReport, 60, poll_interval=5) |
212 def DidRunPageSet(self, tab, results): | 170 timings = tab.EvaluateJavaScript('__get_timings()').split(',') |
213 self.MeasureMemory(tab, results) | 171 results.Add('t', 'ms', [int(t) for t in timings], chart_name='times') |
214 self.MeasureIO(tab, results) | |
OLD | NEW |