Changeset 236996 in webkit
- Timestamp:
- Oct 9, 2018, 8:15:39 PM (8 years ago)
- Location:
- trunk/Websites/perf.webkit.org
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
public/include/manifest-generator.php (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Websites/perf.webkit.org/ChangeLog
r236956 r236996 1 2018-10-09 Ryosuke Niwa <rniwa@webkit.org> 2 3 ManifestGenerator shouldn't need more than 1GB of memory or run for 30 seconds 4 https://bugs.webkit.org/show_bug.cgi?id=190393 5 6 Reviewed by Antti Koivisto and unofficially reviewed by Dewei Zhu. 7 8 This patch reduces the runtime of /api/manifest from 13s to 7s and reduces the memory requirement from 9 1GB to 400MB for the internal dashboard in my local testing. 10 11 The biggest perf win comes from avoid running a complex query over test_configurations to compute 12 the latest modified date across different test configuration types ("current" vs. "baseline"). 13 Instead, we now fetch the entire table row by row and compute the latest modified date in memory. 14 15 Also call intval in many more places to avoid generating double quotes, which is a pretty significant 16 proportion of the JSON file size at this point. 17 18 Finally, use references in more places to avoid deep copying of arrays. 19 20 * public/include/manifest-generator.php: 21 (ManifestGenerator::generate): Skip the generation of "dashboard" since it's only used by v1 UI. 22 (ManifestGenerator::tests): Don't copy each row. 23 (ManifestGenerator::metrics): Ditto. 24 (ManifestGenerator::platforms): Implement the aforementioned optimization. Instead of grouping 25 test configurations for a given metric and platform together, fetch them all and do in-memory 26 processing in PHP. Avoid more copying as well. 27 (ManifestGenerator::repositories): Avoid more copying. 28 (ManifestGenerator::bug_trackers): Ditto. 29 (ManifestGenerator::fetch_triggerables): Ditto. 30 1 31 2018-10-08 Ryosuke Niwa <rniwa@webkit.org> 2 32 -
trunk/Websites/perf.webkit.org/public/include/manifest-generator.php
r236454 r236996 30 30 $metrics = (object)$this->metrics(); 31 31 $platforms = (object)$this->platforms($platform_table, false); 32 $dashboard = (object)$this->platforms($platform_table, true);33 32 $repositories = (object)$this->repositories($repositories_table, $repositories_with_commit); 34 33 … … 38 37 'metrics' => &$metrics, 39 38 'all' => &$platforms, 40 'dashboard' => &$dashboard,39 'dashboard' => (object)array(), // Only used by v1 UI. 41 40 'repositories' => &$repositories, 42 41 'builders' => (object)$this->builders(), … … 65 64 if (!$tests_table) 66 65 return $tests; 67 foreach ($tests_table as $test_row) {66 foreach ($tests_table as &$test_row) { 68 67 $tests[$test_row['test_id']] = array( 69 68 'name' => $test_row['test_name'], 70 69 'url' => $test_row['test_url'], 71 'parentId' => $test_row['test_parent'] ,70 'parentId' => $test_row['test_parent'] ? intval($test_row['test_parent']) : NULL, 72 71 ); 73 72 } … … 80 79 if (!$metrics_table) 81 80 return $metrics; 82 foreach ($metrics_table as $row) {81 foreach ($metrics_table as &$row) { 83 82 $metrics[$row['metric_id']] = array( 84 83 'name' => $row['metric_name'], 85 'test' => $row['metric_test'],84 'test' => intval($row['metric_test']), 86 85 'aggregator' => $row['aggregator_name']); 87 86 } … … 89 88 } 90 89 91 private function platforms( $platform_table, $is_dashboard) {92 $ metrics = $this->db->query_and_fetch_all('SELECT config_metric AS metric_id, config_platform AS platform_id,93 extract(epoch from max(config_runs_last_modified) at time zone \'utc\') * 1000 AS last_modified, bool_or(config_is_in_dashboard) AS in_dashboard94 FROM test_configurations GROUP BY config_metric, config_platform ORDER BY config_platform');90 private function platforms(&$platform_table, $is_dashboard) { 91 $config_query = $this->db->query('SELECT config_platform, config_metric, 92 extract(epoch from config_runs_last_modified at time zone \'utc\') * 1000 AS last_modified 93 FROM test_configurations'); 95 94 96 95 $platform_metrics = array(); 97 96 98 if ($ metrics) {97 if ($config_query) { 99 98 $current_platform_entry = null; 100 foreach ($metrics as $metric_row) { 101 if ($is_dashboard && !Database::is_true($metric_row['in_dashboard'])) 102 continue; 103 104 $platform_id = $metric_row['platform_id']; 105 if (!$current_platform_entry || $current_platform_entry['id'] != $platform_id) { 106 $current_platform_entry = &array_ensure_item_has_array($platform_metrics, $platform_id); 107 $current_platform_entry['id'] = $platform_id; 108 array_ensure_item_has_array($current_platform_entry, 'metrics'); 109 array_ensure_item_has_array($current_platform_entry, 'last_modified'); 99 $last_modified_map = array(); 100 while (1) { 101 $config_row = $this->db->fetch_next_row($config_query); 102 if (!$config_row) 103 break; 104 105 $platform_id = $config_row['config_platform']; 106 $metric_id = $config_row['config_metric']; 107 $last_modified = intval($config_row['last_modified']); 108 109 $key = $platform_id . '-' . $metric_id; 110 if (array_key_exists($key, $last_modified_map)) { 111 $last_modified_map[$key] = max($last_modified_map[$key], $last_modified); 112 continue; 110 113 } 111 112 array_push($current_platform_entry['metrics'], $metric_row['metric_id']); 113 array_push($current_platform_entry['last_modified'], intval($metric_row['last_modified'])); 114 $last_modified_map[$key] = $last_modified; 115 116 $current_platform_entry = &array_ensure_item_has_array($platform_metrics, $platform_id); 117 array_ensure_item_has_array($current_platform_entry, 'metrics'); 118 array_push($current_platform_entry['metrics'], intval($metric_id)); 114 119 } 115 120 } … … 118 123 $platforms = array(); 119 124 if ($platform_table) { 120 foreach ($platform_table as $platform_row) {125 foreach ($platform_table as &$platform_row) { 121 126 if (Database::is_true($platform_row['platform_hidden'])) 122 127 continue; 123 128 $id = $platform_row['platform_id']; 124 129 if (array_key_exists($id, $platform_metrics)) { 130 $metrics = &$platform_metrics[$id]['metrics']; 131 $last_modified = array(); 132 foreach ($metrics as $metric_id) 133 array_push($last_modified, $last_modified_map[$id . '-' . $metric_id]); 125 134 $platforms[$id] = array( 126 'name' => $platform_row['platform_name'], 127 'metrics' => $platform_metrics[$id]['metrics'], 128 'lastModified' => $platform_metrics[$id]['last_modified']); 135 'name' => &$platform_row['platform_name'], 136 'metrics' => &$metrics, 137 'lastModified' => &$last_modified 138 ); 129 139 } 130 140 } … … 137 147 if (!$repositories_table) 138 148 return $repositories; 139 foreach ($repositories_table as $row) {149 foreach ($repositories_table as &$row) { 140 150 $repositories[$row['repository_id']] = array( 141 151 'name' => $row['repository_name'], … … 154 164 return array(); 155 165 $builders = array(); 156 foreach ($builders_table as $row)166 foreach ($builders_table as &$row) 157 167 $builders[$row['builder_id']] = array('name' => $row['builder_name'], 'buildUrl' => $row['builder_build_url']); 158 168 … … 173 183 $bug_trackers_table = $this->db->fetch_table('bug_trackers'); 174 184 if ($bug_trackers_table) { 175 foreach ($bug_trackers_table as $row) {185 foreach ($bug_trackers_table as &$row) { 176 186 $bug_trackers[$row['tracker_id']] = array( 177 187 'name' => $row['tracker_name'], … … 217 227 array_ensure_item_has_array($repository_set_by_group, $group_id); 218 228 array_push($repository_set_by_group[$group_id], array( 219 'repository' => $repository_row['trigrepo_repository'],229 'repository' => intval($repository_row['trigrepo_repository']), 220 230 'acceptsPatch' => Database::is_true($repository_row['trigrepo_accepts_patch']))); 221 231 } … … 228 238 $repository_list = array_get($repository_set_by_group, $group_id, array()); 229 239 array_push($triggerable['repositoryGroups'], array( 230 'id' => $group_row['repositorygroup_id'],240 'id' => intval($group_row['repositorygroup_id']), 231 241 'name' => $group_row['repositorygroup_name'], 232 242 'description' => $group_row['repositorygroup_description'], … … 235 245 'repositories' => $repository_list)); 236 246 // V2 UI compatibility. 237 foreach ($repository_list as $repository_data) {247 foreach ($repository_list as &$repository_data) { 238 248 $repository_id = $repository_data['repository']; 239 249 $set = &$triggerable_id_to_repository_set[$triggerable_id]; … … 254 264 continue; 255 265 $triggerable = &$id_to_triggerable[$triggerable_id]; 256 array_push($triggerable['configurations'], array( $row['trigconfig_test'], $row['trigconfig_platform']));266 array_push($triggerable['configurations'], array(intval($row['trigconfig_test']), intval($row['trigconfig_platform']))); 257 267 } 258 268 }
Note:
See TracChangeset
for help on using the changeset viewer.