forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathprefetch_benchmark.py
executable file
·163 lines (134 loc) · 6.05 KB
/
prefetch_benchmark.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/python
#
# Copyright 2016 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.
"""Loads a web page with speculative prefetch, and collects loading metrics."""
import argparse
import logging
import os
import random
import sys
import time
_SRC_PATH = os.path.abspath(os.path.join(
os.path.dirname(__file__), os.pardir, os.pardir))
sys.path.append(os.path.join(
_SRC_PATH, 'tools', 'android', 'customtabs_benchmark', 'scripts'))
import customtabs_benchmark
import chrome_setup
import device_setup
sys.path.append(os.path.join(_SRC_PATH, 'tools', 'android', 'loading'))
import controller
from options import OPTIONS
sys.path.append(os.path.join(_SRC_PATH, 'build', 'android'))
import devil_chromium
sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil'))
from devil.android import flag_changer
from devil.android.sdk import intent
import prefetch_predictor_common
def _CreateArgumentParser():
"""Creates and returns the argument parser."""
parser = argparse.ArgumentParser(
('Loads a URL with the resource_prefetch_predictor and prints loading '
'metrics.'), parents=[OPTIONS.GetParentParser()])
parser.add_argument('--device', help='Device ID')
parser.add_argument('--database',
help=('File containing the predictor database, as '
'obtained from generate_database.py.'))
parser.add_argument('--url', help='URL to load.')
parser.add_argument('--prefetch_delays_ms',
help='List of prefetch delays in ms. -1 to disable '
'prefetch. Runs will randomly select one delay in the '
'list.')
parser.add_argument('--output_filename',
help='CSV file to append the result to.')
parser.add_argument('--network_condition',
help='Network condition for emulation.')
parser.add_argument('--wpr_archive', help='WPR archive path.')
parser.add_argument('--once', help='Only run once.', action='store_true')
return parser
def _Setup(device, database_filename):
"""Sets up a device and returns an instance of RemoteChromeController."""
chrome_controller = prefetch_predictor_common.Setup(device)
chrome_package = OPTIONS.ChromePackage()
device.ForceStop(chrome_package.package)
chrome_controller.ResetBrowserState()
device_database_filename = prefetch_predictor_common.DatabaseDevicePath()
owner = group = None
# Make sure that the speculative prefetch predictor is enabled to ensure
# that the disk database is re-created.
with flag_changer.CustomCommandLineFlags(
device, chrome_package.cmdline_file, ['--disable-fre']):
# Launch Chrome for the first time to recreate the local state.
launch_intent = intent.Intent(
action='android.intent.action.MAIN',
package=chrome_package.package,
activity=chrome_package.activity)
device.StartActivity(launch_intent, blocking=True)
time.sleep(5)
device.ForceStop(chrome_package.package)
assert device.FileExists(device_database_filename)
stats = device.StatPath(device_database_filename)
owner = stats['st_owner']
group = stats['st_group']
# Now push the database. Needs to be done after the first launch, otherwise
# the profile directory is owned by root. Also change the owner of the
# database, since adb push sets it to root.
database_content = open(database_filename, 'r').read()
device.WriteFile(device_database_filename, database_content, force_push=True)
device.RunShellCommand(
['chown', '%s:%s' % (owner, group), device_database_filename],
as_root=True, check_return=True)
def _RunOnce(device, database_filename, url, prefetch_delay_ms,
output_filename, wpr_archive, network_condition):
_Setup(device, database_filename)
disable_prefetch = prefetch_delay_ms == -1
# Startup tracing to ease debugging.
chrome_args = (chrome_setup.CHROME_ARGS
+ ['--trace-startup', '--trace-startup-duration=20'])
# Speculative Prefetch is enabled through an experiment.
chrome_args.extend([
'--force-fieldtrials=trial/group',
'--force-fieldtrial-params=trial.group:mode/external-prefetching',
'--enable-features=SpeculativeResourcePrefetching<trial'])
chrome_controller = controller.RemoteChromeController(device)
device.ForceStop(OPTIONS.ChromePackage().package)
chrome_controller.AddChromeArguments(chrome_args)
with device_setup.RemoteWprHost(
device, wpr_archive, record=False,
network_condition_name=network_condition) as wpr:
logging.info('WPR arguments: ' + ' '.join(wpr.chrome_args))
chrome_args += wpr.chrome_args
prefetch_mode = 'disabled' if disable_prefetch else 'speculative_prefetch'
result = customtabs_benchmark.RunOnce(
device, url, warmup=True, speculation_mode=prefetch_mode,
delay_to_may_launch_url=2000,
delay_to_launch_url=prefetch_delay_ms, cold=False,
chrome_args=chrome_args, reset_chrome_state=False)
data_point = customtabs_benchmark.ParseResult(result)
with open(output_filename, 'a') as f:
f.write(','.join(str(x) for x in data_point) + '\n')
def main():
logging.basicConfig(level=logging.INFO)
devil_chromium.Initialize()
parser = _CreateArgumentParser()
args = parser.parse_args()
OPTIONS.SetParsedArgs(args)
if os.path.exists(args.output_filename):
logging.error('Output file %s already exists.' % args.output_filename)
sys.exit(1)
device = prefetch_predictor_common.FindDevice(args.device)
if device is None:
logging.error('Could not find device: %s.', args.device)
sys.exit(1)
delays = [int(x) for x in args.prefetch_delays_ms.split(',')]
with open(args.output_filename, 'w') as f:
f.write(','.join(customtabs_benchmark.RESULT_FIELDS) + '\n')
while True:
delay = delays[random.randint(0, len(delays) - 1)]
_RunOnce(device, args.database, args.url, delay, args.output_filename,
args.wpr_archive, args.network_condition)
if args.once:
return
if __name__ == '__main__':
main()