| 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 |