Created
July 28, 2020 11:09
-
-
Save CreepySkeleton/2e3e54008f987749cd1cbf31f8f1f0e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Cargo Build Timings — clap 3.0.0-beta.1</title> | |
<meta charset="utf-8"> | |
<style type="text/css"> | |
html { | |
font-family: sans-serif; | |
} | |
.canvas-container { | |
position: relative; | |
margin-top: 5px; | |
margin-bottom: 5px; | |
} | |
h1 { | |
border-bottom: 1px solid #c0c0c0; | |
} | |
.graph { | |
display: block; | |
} | |
.my-table { | |
margin-top: 20px; | |
margin-bottom: 20px; | |
border-collapse: collapse; | |
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); | |
} | |
.my-table th { | |
color: #d5dde5; | |
background: #1b1e24; | |
border-bottom: 4px solid #9ea7af; | |
border-right: 1px solid #343a45; | |
font-size: 18px; | |
font-weight: 100; | |
padding: 12px; | |
text-align: left; | |
vertical-align: middle; | |
} | |
.my-table th:first-child { | |
border-top-left-radius: 3px; | |
} | |
.my-table th:last-child { | |
border-top-right-radius: 3px; | |
border-right:none; | |
} | |
.my-table tr { | |
border-top: 1px solid #c1c3d1; | |
border-bottom: 1px solid #c1c3d1; | |
font-size: 16px; | |
font-weight: normal; | |
} | |
.my-table tr:first-child { | |
border-top:none; | |
} | |
.my-table tr:last-child { | |
border-bottom:none; | |
} | |
.my-table tr:nth-child(odd) td { | |
background: #ebebeb; | |
} | |
.my-table tr:last-child td:first-child { | |
border-bottom-left-radius:3px; | |
} | |
.my-table tr:last-child td:last-child { | |
border-bottom-right-radius:3px; | |
} | |
.my-table td { | |
background: #ffffff; | |
padding: 10px; | |
text-align: left; | |
vertical-align: middle; | |
font-weight: 300; | |
font-size: 14px; | |
border-right: 1px solid #C1C3D1; | |
} | |
.my-table td:last-child { | |
border-right: 0px; | |
} | |
.summary-table td:first-child { | |
vertical-align: top; | |
text-align: right; | |
} | |
.input-table td { | |
text-align: center; | |
} | |
.error-text { | |
color: #e80000; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Cargo Build Timings</h1> | |
<table class="my-table summary-table"> | |
<tr> | |
<td>Targets:</td><td>clap 3.0.0-beta.1 (lib)</td> | |
</tr> | |
<tr> | |
<td>Profile:</td><td>dev</td> | |
</tr> | |
<tr> | |
<td>Fresh units:</td><td>0</td> | |
</tr> | |
<tr> | |
<td>Dirty units:</td><td>15</td> | |
</tr> | |
<tr> | |
<td>Total units:</td><td>15</td> | |
</tr> | |
<tr> | |
<td>Max concurrency:</td><td>2 (jobs=2 ncpu=2)</td> | |
</tr> | |
<tr> | |
<td>Build start:</td><td>2020-07-28T11:08:02Z</td> | |
</tr> | |
<tr> | |
<td>Total time:</td><td>14.3s</td> | |
</tr> | |
<tr> | |
<td>rustc:</td><td>rustc 1.47.0-nightly (6c8927b0c 2020-07-26)<br>Host: x86_64-unknown-linux-gnu<br>Target: x86_64-unknown-linux-gnu</td> | |
</tr> | |
<tr> | |
<td>Max (global) rustc threads concurrency:</td><td>0</td> | |
</tr> | |
</table> | |
<table class="input-table"> | |
<tr> | |
<td><label for="min-unit-time">Min unit time:</label></td> | |
<td><label for="scale">Scale:</label></td> | |
</tr> | |
<tr> | |
<td><input type="range" min="0" max="30" step="0.1" value="0" id="min-unit-time"></td> | |
<td><input type="range" min="1" max="50" value="20" id="scale"></td> | |
</tr> | |
<tr> | |
<td><output for="min-unit-time" id="min-unit-time-output"></output></td> | |
<td><output for="scale" id="scale-output"></output></td> | |
</tr> | |
</table> | |
<div id="pipeline-container" class="canvas-container"> | |
<canvas id="pipeline-graph" class="graph" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas> | |
<canvas id="pipeline-graph-lines" style="position: absolute; left: 0; top: 0; z-index: 1; pointer-events:none;"></canvas> | |
</div> | |
<div class="canvas-container"> | |
<canvas id="timing-graph" class="graph"></canvas> | |
</div> | |
<table class="my-table"> | |
<thead> | |
<tr> | |
<th></th> | |
<th>Unit</th> | |
<th>Total</th> | |
<th>Codegen</th> | |
<th>Features</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr> | |
<td>1.</td> | |
<td>clap v3.0.0-beta.1</td> | |
<td>10.7s</td> | |
<td>5.2s (48%)</td> | |
<td>std</td> | |
</tr> | |
<tr> | |
<td>2.</td> | |
<td>autocfg v1.0.0</td> | |
<td>1.0s</td> | |
<td>0.7s (69%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>3.</td> | |
<td>hashbrown v0.8.1</td> | |
<td>1.0s</td> | |
<td>0.0s (5%)</td> | |
<td>raw</td> | |
</tr> | |
<tr> | |
<td>4.</td> | |
<td>indexmap v1.5.0</td> | |
<td>0.8s</td> | |
<td>0.1s (11%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>5.</td> | |
<td>textwrap v0.12.1</td> | |
<td>0.7s</td> | |
<td>0.5s (63%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>6.</td> | |
<td>bitflags v1.2.1 custom-build</td> | |
<td>0.6s</td> | |
<td>0.0s (0%)</td> | |
<td>default</td> | |
</tr> | |
<tr> | |
<td>7.</td> | |
<td>indexmap v1.5.0 custom-build</td> | |
<td>0.3s</td> | |
<td>0.0s (0%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>8.</td> | |
<td>hashbrown v0.8.1 custom-build</td> | |
<td>0.3s</td> | |
<td>0.0s (0%)</td> | |
<td>raw</td> | |
</tr> | |
<tr> | |
<td>9.</td> | |
<td>vec_map v0.8.2</td> | |
<td>0.3s</td> | |
<td>0.0s (4%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>10.</td> | |
<td>os_str_bytes v2.3.1</td> | |
<td>0.3s</td> | |
<td>0.1s (39%)</td> | |
<td>raw</td> | |
</tr> | |
<tr> | |
<td>11.</td> | |
<td>indexmap v1.5.0 custom-build (run)</td> | |
<td>0.2s</td> | |
<td>0.0s (0%)</td> | |
<td></td> | |
</tr> | |
<tr> | |
<td>12.</td> | |
<td>unicode-width v0.1.8</td> | |
<td>0.1s</td> | |
<td>0.0s (9%)</td> | |
<td>default</td> | |
</tr> | |
<tr> | |
<td>13.</td> | |
<td>hashbrown v0.8.1 custom-build (run)</td> | |
<td>0.1s</td> | |
<td>0.0s (0%)</td> | |
<td>raw</td> | |
</tr> | |
<tr> | |
<td>14.</td> | |
<td>bitflags v1.2.1</td> | |
<td>0.0s</td> | |
<td>0.0s (15%)</td> | |
<td>default</td> | |
</tr> | |
<tr> | |
<td>15.</td> | |
<td>bitflags v1.2.1 custom-build (run)</td> | |
<td>0.0s</td> | |
<td>0.0s (0%)</td> | |
<td>default</td> | |
</tr> | |
</tbody> | |
</table> | |
<script> | |
DURATION = 15; | |
const UNIT_DATA = [ | |
{ | |
"i": 0, | |
"name": "autocfg", | |
"version": "1.0.0", | |
"mode": "todo", | |
"target": "", | |
"start": 0.13, | |
"duration": 1.02, | |
"rmeta_time": 0.32, | |
"unlocked_units": [ | |
7, | |
8 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 1, | |
"name": "bitflags", | |
"version": "1.2.1", | |
"mode": "todo", | |
"target": " custom-build", | |
"start": 0.13, | |
"duration": 0.61, | |
"rmeta_time": 0.61, | |
"unlocked_units": [ | |
5 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 2, | |
"name": "unicode-width", | |
"version": "0.1.8", | |
"mode": "todo", | |
"target": "", | |
"start": 0.73, | |
"duration": 0.13, | |
"rmeta_time": 0.11, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [ | |
6 | |
] | |
}, | |
{ | |
"i": 3, | |
"name": "vec_map", | |
"version": "0.8.2", | |
"mode": "todo", | |
"target": "", | |
"start": 0.86, | |
"duration": 0.26, | |
"rmeta_time": 0.25, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 4, | |
"name": "os_str_bytes", | |
"version": "2.3.1", | |
"mode": "todo", | |
"target": "", | |
"start": 1.12, | |
"duration": 0.25, | |
"rmeta_time": 0.15, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 5, | |
"name": "bitflags", | |
"version": "1.2.1", | |
"mode": "run-custom-build", | |
"target": " custom-build (run)", | |
"start": 1.14, | |
"duration": 0.03, | |
"rmeta_time": 0.03, | |
"unlocked_units": [ | |
9 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 6, | |
"name": "textwrap", | |
"version": "0.12.1", | |
"mode": "todo", | |
"target": "", | |
"start": 1.17, | |
"duration": 0.73, | |
"rmeta_time": 0.27, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 7, | |
"name": "hashbrown", | |
"version": "0.8.1", | |
"mode": "todo", | |
"target": " custom-build", | |
"start": 1.38, | |
"duration": 0.33, | |
"rmeta_time": 0.33, | |
"unlocked_units": [ | |
10 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 8, | |
"name": "indexmap", | |
"version": "1.5.0", | |
"mode": "todo", | |
"target": " custom-build", | |
"start": 1.7, | |
"duration": 0.35, | |
"rmeta_time": 0.35, | |
"unlocked_units": [ | |
12 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 9, | |
"name": "bitflags", | |
"version": "1.2.1", | |
"mode": "todo", | |
"target": "", | |
"start": 1.9, | |
"duration": 0.05, | |
"rmeta_time": 0.04, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 10, | |
"name": "hashbrown", | |
"version": "0.8.1", | |
"mode": "run-custom-build", | |
"target": " custom-build (run)", | |
"start": 1.95, | |
"duration": 0.08, | |
"rmeta_time": 0.08, | |
"unlocked_units": [ | |
11 | |
], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 11, | |
"name": "hashbrown", | |
"version": "0.8.1", | |
"mode": "todo", | |
"target": "", | |
"start": 2.03, | |
"duration": 0.96, | |
"rmeta_time": 0.91, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [ | |
13 | |
] | |
}, | |
{ | |
"i": 12, | |
"name": "indexmap", | |
"version": "1.5.0", | |
"mode": "run-custom-build", | |
"target": " custom-build (run)", | |
"start": 2.05, | |
"duration": 0.15, | |
"rmeta_time": 0.15, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
}, | |
{ | |
"i": 13, | |
"name": "indexmap", | |
"version": "1.5.0", | |
"mode": "todo", | |
"target": "", | |
"start": 2.95, | |
"duration": 0.83, | |
"rmeta_time": 0.74, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [ | |
14 | |
] | |
}, | |
{ | |
"i": 14, | |
"name": "clap", | |
"version": "3.0.0-beta.1", | |
"mode": "todo", | |
"target": "", | |
"start": 3.68, | |
"duration": 10.66, | |
"rmeta_time": 5.5, | |
"unlocked_units": [], | |
"unlocked_rmeta_units": [] | |
} | |
]; | |
const CONCURRENCY_DATA = [ | |
{ | |
"t": 0.12576291, | |
"active": 1, | |
"waiting": 4, | |
"inactive": 10, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.125933632, | |
"active": 1, | |
"waiting": 4, | |
"inactive": 10, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.126119254, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 10, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.126286279, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 10, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.443344183, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 10, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.73238512, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 9, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.732910028, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 9, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.8470938, | |
"active": 2, | |
"waiting": 4, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.858754722, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 0.859110253, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.111117642, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.12237413, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.12274702, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 8, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.142064275, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 6, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.142850575, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 6, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.170805776, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.171486587, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.277015056, | |
"active": 2, | |
"waiting": 3, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.37530493, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.375570775, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.44460527, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 5, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.701894791, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.702549865, | |
"active": 2, | |
"waiting": 2, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.90260137, | |
"active": 2, | |
"waiting": 1, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.903631844, | |
"active": 2, | |
"waiting": 1, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.9441262240000001, | |
"active": 2, | |
"waiting": 1, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.951607175, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 1.952594942, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 4, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.029549633, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 3, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.030651966, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 3, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.048210788, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.048655173, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.200405063, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201042057, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201097337, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201129326, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201175263, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201204851, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201232197, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201257949, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201283099, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201308371, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201333489, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.201360198, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.701499967, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 2, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.943212056, | |
"active": 1, | |
"waiting": 1, | |
"inactive": 1, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.943426176, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 1, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.947475161, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 1, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 2.988472181, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 1, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 3.488748966, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 1, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 3.683227213, | |
"active": 1, | |
"waiting": 1, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 3.6839121390000003, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 3.684179471, | |
"active": 2, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 3.77881251, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 4.27913731, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 4.779439192, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 5.279742387, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 5.780009853, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 6.280298938, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 6.780566183, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 7.280839307, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 7.781107064, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 8.281387487, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 8.781657803, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 9.182027205, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 9.682277752, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 10.182539442, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 10.682859814, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 11.183197497, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 11.683422457, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 12.183666892, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 12.683923106, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 13.184180044, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 13.684430932, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 14.184678927, | |
"active": 1, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
}, | |
{ | |
"t": 14.343929919, | |
"active": 0, | |
"waiting": 0, | |
"inactive": 0, | |
"rustc_parallelism": 0 | |
} | |
]; | |
const CPU_USAGE = [ | |
[ | |
0.443356726, | |
100.0 | |
], | |
[ | |
0.73238574, | |
94.73684210526316 | |
], | |
[ | |
0.847094362, | |
100.0 | |
], | |
[ | |
1.111119338, | |
100.0 | |
], | |
[ | |
1.277015867, | |
96.96969696969697 | |
], | |
[ | |
1.44460722, | |
100.0 | |
], | |
[ | |
1.701895512, | |
100.0 | |
], | |
[ | |
1.9026030980000002, | |
100.0 | |
], | |
[ | |
2.029549934, | |
100.0 | |
], | |
[ | |
2.200490244, | |
100.0 | |
], | |
[ | |
2.701500893, | |
50.0 | |
], | |
[ | |
2.9432128779999998, | |
51.02040816326531 | |
], | |
[ | |
3.488749808, | |
53.7037037037037 | |
], | |
[ | |
3.683227862, | |
50.0 | |
], | |
[ | |
4.27913841, | |
57.5 | |
], | |
[ | |
4.779440335, | |
50.0 | |
], | |
[ | |
5.279743491, | |
50.0 | |
], | |
[ | |
5.780011351, | |
50.0 | |
], | |
[ | |
6.280299794, | |
50.0 | |
], | |
[ | |
6.78056706, | |
49.494949494949495 | |
], | |
[ | |
7.280840217, | |
50.495049504950494 | |
], | |
[ | |
7.781108221, | |
50.0 | |
], | |
[ | |
8.281388372, | |
50.505050505050505 | |
], | |
[ | |
8.781659015, | |
49.494949494949495 | |
], | |
[ | |
9.182047587, | |
50.617283950617285 | |
], | |
[ | |
9.68227892, | |
77.22772277227722 | |
], | |
[ | |
10.182540723, | |
100.0 | |
], | |
[ | |
10.682861241, | |
100.0 | |
], | |
[ | |
11.183198327, | |
100.0 | |
], | |
[ | |
11.68342384, | |
98.98989898989899 | |
], | |
[ | |
12.183667824, | |
100.0 | |
], | |
[ | |
12.683924002, | |
97.95918367346938 | |
], | |
[ | |
13.184181107, | |
95.95959595959596 | |
], | |
[ | |
13.684432358, | |
95.87628865979381 | |
], | |
[ | |
14.184679808, | |
86.45833333333333 | |
] | |
]; | |
// Position of the vertical axis. | |
const X_LINE = 50; | |
// General-use margin size. | |
const MARGIN = 5; | |
// Position of the horizontal axis, relative to the bottom. | |
const Y_LINE = 35; | |
// Minimum distance between time tick labels. | |
const MIN_TICK_DIST = 50; | |
// Radius for rounded rectangle corners. | |
const RADIUS = 3; | |
// Height of unit boxes. | |
const BOX_HEIGHT = 25; | |
// Distance between Y tick marks on the unit graph. | |
const Y_TICK_DIST = BOX_HEIGHT + 2; | |
// Rects used for mouseover detection. | |
// Objects of {x, y, x2, y2, i} where `i` is the index into UNIT_DATA. | |
let HIT_BOXES = []; | |
// Index into UNIT_DATA of the last unit hovered over by mouse. | |
let LAST_HOVER = null; | |
// Key is unit index, value is {x, y, width, rmeta_x} of the box. | |
let UNIT_COORDS = {}; | |
// Map of unit index to the index it was unlocked by. | |
let REVERSE_UNIT_DEPS = {}; | |
let REVERSE_UNIT_RMETA_DEPS = {}; | |
for (let n=0; n<UNIT_DATA.length; n++) { | |
let unit = UNIT_DATA[n]; | |
for (let unlocked of unit.unlocked_units) { | |
REVERSE_UNIT_DEPS[unlocked] = n; | |
} | |
for (let unlocked of unit.unlocked_rmeta_units) { | |
REVERSE_UNIT_RMETA_DEPS[unlocked] = n; | |
} | |
} | |
function render_pipeline_graph() { | |
if (UNIT_DATA.length == 0) { | |
return; | |
} | |
let g = document.getElementById('pipeline-graph'); | |
HIT_BOXES.length = 0; | |
g.onmousemove = pipeline_mousemove; | |
const min_time = document.getElementById('min-unit-time').valueAsNumber; | |
const units = UNIT_DATA.filter(unit => unit.duration >= min_time); | |
const graph_height = Y_TICK_DIST * units.length; | |
const {ctx, graph_width, canvas_width, canvas_height, px_per_sec} = draw_graph_axes('pipeline-graph', graph_height); | |
const container = document.getElementById('pipeline-container'); | |
container.style.width = canvas_width; | |
container.style.height = canvas_height; | |
// Canvas for hover highlights. This is a separate layer to improve performance. | |
const linectx = setup_canvas('pipeline-graph-lines', canvas_width, canvas_height); | |
linectx.clearRect(0, 0, canvas_width, canvas_height); | |
// Draw Y tick marks. | |
for (let n=1; n<units.length; n++) { | |
const y = graph_height - (n * Y_TICK_DIST); | |
ctx.beginPath(); | |
ctx.moveTo(X_LINE, y); | |
ctx.lineTo(X_LINE-5, y); | |
ctx.stroke(); | |
} | |
// Draw Y labels. | |
ctx.textAlign = 'end'; | |
for (let n=0; n<units.length; n++) { | |
let y = MARGIN + (Y_TICK_DIST * (n + 1)) - 13; | |
ctx.fillText(n+1, X_LINE-4, y); | |
} | |
// Draw the graph. | |
ctx.save(); | |
ctx.translate(X_LINE, MARGIN); | |
// Compute x,y coordinate of each block. | |
UNIT_COORDS = {}; | |
for (i=0; i<units.length; i++) { | |
let unit = units[i]; | |
let y = i * Y_TICK_DIST + 1; | |
let x = px_per_sec * unit.start; | |
let rmeta_x = null; | |
if (unit.rmeta_time != null) { | |
rmeta_x = x + px_per_sec * unit.rmeta_time; | |
} | |
let width = Math.max(px_per_sec * unit.duration, 1.0); | |
UNIT_COORDS[unit.i] = {x, y, width, rmeta_x}; | |
} | |
// Draw the blocks. | |
for (i=0; i<units.length; i++) { | |
let unit = units[i]; | |
let {x, y, width, rmeta_x} = UNIT_COORDS[unit.i]; | |
HIT_BOXES.push({x: X_LINE+x, y:MARGIN+y, x2: X_LINE+x+width, y2: MARGIN+y+BOX_HEIGHT, i: unit.i}); | |
ctx.beginPath(); | |
ctx.fillStyle = unit.mode == 'run-custom-build' ? '#f0b165' : '#95cce8'; | |
roundedRect(ctx, x, y, width, BOX_HEIGHT, RADIUS); | |
ctx.fill(); | |
if (unit.rmeta_time != null) { | |
ctx.beginPath(); | |
ctx.fillStyle = '#aa95e8'; | |
let ctime = unit.duration - unit.rmeta_time; | |
roundedRect(ctx, rmeta_x, y, px_per_sec * ctime, BOX_HEIGHT, RADIUS); | |
ctx.fill(); | |
} | |
ctx.fillStyle = "#000"; | |
ctx.textAlign = 'start'; | |
ctx.textBaseline = 'hanging'; | |
ctx.font = '14px sans-serif'; | |
const label = `${unit.name}${unit.target} ${unit.duration}s`; | |
const text_info = ctx.measureText(label); | |
const label_x = Math.min(x + 5.0, canvas_width - text_info.width - X_LINE); | |
ctx.fillText(label, label_x, y + BOX_HEIGHT / 2 - 6); | |
draw_dep_lines(ctx, unit.i, false); | |
} | |
ctx.restore(); | |
} | |
// Draws lines from the given unit to the units it unlocks. | |
function draw_dep_lines(ctx, unit_idx, highlighted) { | |
const unit = UNIT_DATA[unit_idx]; | |
const {x, y, rmeta_x} = UNIT_COORDS[unit_idx]; | |
ctx.save(); | |
for (const unlocked of unit.unlocked_units) { | |
draw_one_dep_line(ctx, x, y, unlocked, highlighted); | |
} | |
for (const unlocked of unit.unlocked_rmeta_units) { | |
draw_one_dep_line(ctx, rmeta_x, y, unlocked, highlighted); | |
} | |
ctx.restore(); | |
} | |
function draw_one_dep_line(ctx, from_x, from_y, to_unit, highlighted) { | |
if (to_unit in UNIT_COORDS) { | |
let {x: u_x, y: u_y} = UNIT_COORDS[to_unit]; | |
ctx.strokeStyle = highlighted ? '#000' : '#ddd'; | |
ctx.setLineDash([2]); | |
ctx.beginPath(); | |
ctx.moveTo(from_x, from_y+BOX_HEIGHT/2); | |
ctx.lineTo(from_x-5, from_y+BOX_HEIGHT/2); | |
ctx.lineTo(from_x-5, u_y+BOX_HEIGHT/2); | |
ctx.lineTo(u_x, u_y+BOX_HEIGHT/2); | |
ctx.stroke(); | |
} | |
} | |
function render_timing_graph() { | |
if (CONCURRENCY_DATA.length == 0) { | |
return; | |
} | |
const HEIGHT = 400; | |
const AXIS_HEIGHT = HEIGHT - MARGIN - Y_LINE; | |
const TOP_MARGIN = 10; | |
const GRAPH_HEIGHT = AXIS_HEIGHT - TOP_MARGIN; | |
const {canvas_width, graph_width, ctx} = draw_graph_axes('timing-graph', AXIS_HEIGHT); | |
// Draw Y tick marks and labels. | |
let max_v = 0; | |
for (c of CONCURRENCY_DATA) { | |
max_v = Math.max(max_v, c.active, c.waiting, c.inactive); | |
} | |
const px_per_v = GRAPH_HEIGHT / max_v; | |
const {step, tick_dist, num_ticks} = split_ticks(max_v, px_per_v, GRAPH_HEIGHT); | |
ctx.textAlign = 'end'; | |
for (n=0; n<num_ticks; n++) { | |
let y = HEIGHT - Y_LINE - ((n + 1) * tick_dist); | |
ctx.beginPath(); | |
ctx.moveTo(X_LINE, y); | |
ctx.lineTo(X_LINE-5, y); | |
ctx.stroke(); | |
ctx.fillText((n+1) * step, X_LINE-10, y+5); | |
} | |
// Label the Y axis. | |
let label_y = (HEIGHT - Y_LINE) / 2; | |
ctx.save(); | |
ctx.translate(15, label_y); | |
ctx.rotate(3*Math.PI/2); | |
ctx.textAlign = 'center'; | |
ctx.fillText('# Units', 0, 0); | |
ctx.restore(); | |
// Draw the graph. | |
ctx.save(); | |
ctx.translate(X_LINE, MARGIN); | |
function coord(t, v) { | |
return { | |
x: graph_width * (t/DURATION), | |
y: TOP_MARGIN + GRAPH_HEIGHT * (1.0 - (v / max_v)) | |
}; | |
} | |
const cpuFillStyle = 'rgba(250, 119, 0, 0.2)'; | |
if (CPU_USAGE.length > 1) { | |
ctx.beginPath(); | |
ctx.fillStyle = cpuFillStyle; | |
let bottomLeft = coord(CPU_USAGE[0][0], 0); | |
ctx.moveTo(bottomLeft.x, bottomLeft.y); | |
for (let i=0; i < CPU_USAGE.length; i++) { | |
let [time, usage] = CPU_USAGE[i]; | |
let {x, y} = coord(time, usage / 100.0 * max_v); | |
ctx.lineTo(x, y); | |
} | |
let bottomRight = coord(CPU_USAGE[CPU_USAGE.length - 1][0], 0); | |
ctx.lineTo(bottomRight.x, bottomRight.y); | |
ctx.fill(); | |
} | |
function draw_line(style, key) { | |
let first = CONCURRENCY_DATA[0]; | |
let last = coord(first.t, key(first)); | |
ctx.strokeStyle = style; | |
ctx.beginPath(); | |
ctx.moveTo(last.x, last.y); | |
for (let i=1; i<CONCURRENCY_DATA.length; i++) { | |
let c = CONCURRENCY_DATA[i]; | |
let {x, y} = coord(c.t, key(c)); | |
ctx.lineTo(x, last.y); | |
ctx.lineTo(x, y); | |
last = {x, y}; | |
} | |
ctx.stroke(); | |
} | |
draw_line('blue', function(c) {return c.inactive;}); | |
draw_line('red', function(c) {return c.waiting;}); | |
draw_line('green', function(c) {return c.active;}); | |
// Draw a legend. | |
ctx.restore(); | |
ctx.save(); | |
ctx.translate(canvas_width-200, MARGIN); | |
// background | |
ctx.fillStyle = '#fff'; | |
ctx.strokeStyle = '#000'; | |
ctx.lineWidth = 1; | |
ctx.textBaseline = 'middle' | |
ctx.textAlign = 'start'; | |
ctx.beginPath(); | |
ctx.rect(0, 0, 150, 82); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.fillStyle = '#000' | |
ctx.beginPath(); | |
ctx.lineWidth = 2; | |
ctx.strokeStyle = 'red'; | |
ctx.moveTo(5, 10); | |
ctx.lineTo(50, 10); | |
ctx.stroke(); | |
ctx.fillText('Waiting', 54, 11); | |
ctx.beginPath(); | |
ctx.strokeStyle = 'blue'; | |
ctx.moveTo(5, 30); | |
ctx.lineTo(50, 30); | |
ctx.stroke(); | |
ctx.fillText('Inactive', 54, 31); | |
ctx.beginPath(); | |
ctx.strokeStyle = 'green'; | |
ctx.moveTo(5, 50); | |
ctx.lineTo(50, 50); | |
ctx.stroke(); | |
ctx.fillText('Active', 54, 51); | |
ctx.beginPath(); | |
ctx.fillStyle = cpuFillStyle | |
ctx.fillRect(15, 60, 30, 15); | |
ctx.fill(); | |
ctx.fillStyle = 'black'; | |
ctx.fillText('CPU Usage', 54, 71); | |
ctx.restore(); | |
} | |
function setup_canvas(id, width, height) { | |
let g = document.getElementById(id); | |
let dpr = window.devicePixelRatio || 1; | |
g.width = width * dpr; | |
g.height = height * dpr; | |
g.style.width = width; | |
g.style.height = height; | |
let ctx = g.getContext('2d'); | |
ctx.scale(dpr, dpr); | |
return ctx; | |
} | |
function draw_graph_axes(id, graph_height) { | |
const scale = document.getElementById('scale').valueAsNumber; | |
// Cap the size of the graph. It is hard to view if it is too large, and | |
// browsers may not render a large graph because it takes too much memory. | |
// 4096 is still ridiculously large, and probably won't render on mobile | |
// browsers, but should be ok for many desktop environments. | |
const graph_width = Math.min(scale * DURATION, 4096); | |
const px_per_sec = graph_width / DURATION; | |
const canvas_width = Math.max(graph_width + X_LINE + 30, X_LINE + 250); | |
const canvas_height = graph_height + MARGIN + Y_LINE; | |
let ctx = setup_canvas(id, canvas_width, canvas_height); | |
ctx.fillStyle = '#f7f7f7'; | |
ctx.fillRect(0, 0, canvas_width, canvas_height); | |
ctx.lineWidth = 2; | |
ctx.font = '16px sans-serif'; | |
ctx.textAlign = 'center'; | |
// Draw main axes. | |
ctx.beginPath(); | |
ctx.moveTo(X_LINE, MARGIN); | |
ctx.lineTo(X_LINE, graph_height + MARGIN); | |
ctx.lineTo(X_LINE+graph_width+20, graph_height + MARGIN); | |
ctx.stroke(); | |
// Draw X tick marks. | |
const {step, tick_dist, num_ticks} = split_ticks(DURATION, px_per_sec, graph_width); | |
ctx.fillStyle = '#303030'; | |
for (let n=0; n<num_ticks; n++) { | |
const x = X_LINE + ((n + 1) * tick_dist); | |
ctx.beginPath(); | |
ctx.moveTo(x, canvas_height-Y_LINE); | |
ctx.lineTo(x, canvas_height-Y_LINE+5); | |
ctx.stroke(); | |
ctx.fillText(`${(n+1) * step}s`, x, canvas_height - Y_LINE + 20); | |
} | |
// Draw vertical lines. | |
ctx.strokeStyle = '#e6e6e6'; | |
ctx.setLineDash([2, 4]); | |
for (n=0; n<num_ticks; n++) { | |
const x = X_LINE + ((n + 1) * tick_dist); | |
ctx.beginPath(); | |
ctx.moveTo(x, MARGIN); | |
ctx.lineTo(x, MARGIN+graph_height); | |
ctx.stroke(); | |
} | |
ctx.strokeStyle = '#000'; | |
ctx.setLineDash([]); | |
return {canvas_width, canvas_height, graph_width, graph_height, ctx, px_per_sec}; | |
} | |
// Determine the spacing and number of ticks along an axis. | |
function split_ticks(max_value, px_per_v, max_px) { | |
const max_ticks = Math.floor(max_px / MIN_TICK_DIST); | |
if (max_ticks <= 1) { | |
// Graph is too small for even 1 tick. | |
return {step: max_value, tick_dist: max_px, num_ticks: 1}; | |
} | |
let step; | |
if (max_value <= max_ticks) { | |
step = 1; | |
} else if (max_value <= max_ticks * 2) { | |
step = 2; | |
} else if (max_value <= max_ticks * 4) { | |
step = 4; | |
} else if (max_value <= max_ticks * 5) { | |
step = 5; | |
} else { | |
step = 10; | |
let count = 0; | |
while (true) { | |
if (count > 100) { | |
throw Error("tick loop too long"); | |
} | |
count += 1; | |
if (max_value <= max_ticks * step) { | |
break; | |
} | |
step += 10; | |
} | |
} | |
const tick_dist = px_per_v * step; | |
const num_ticks = Math.floor(max_value / step); | |
return {step, tick_dist, num_ticks}; | |
} | |
function codegen_time(unit) { | |
if (unit.rmeta_time == null) { | |
return null; | |
} | |
let ctime = unit.duration - unit.rmeta_time; | |
return [unit.rmeta_time, ctime]; | |
} | |
function roundedRect(ctx, x, y, width, height, r) { | |
r = Math.min(r, width, height); | |
ctx.beginPath(); | |
ctx.moveTo(x+r, y); | |
ctx.lineTo(x+width-r, y); | |
ctx.arc(x+width-r, y+r, r, 3*Math.PI/2, 0); | |
ctx.lineTo(x+width, y+height-r); | |
ctx.arc(x+width-r, y+height-r, r, 0, Math.PI/2); | |
ctx.lineTo(x+r, y+height); | |
ctx.arc(x+r, y+height-r, r, Math.PI/2, Math.PI); | |
ctx.lineTo(x, y-r); | |
ctx.arc(x+r, y+r, r, Math.PI, 3*Math.PI/2); | |
ctx.closePath(); | |
} | |
function pipeline_mouse_hit(event) { | |
// This brute-force method can be optimized if needed. | |
for (let box of HIT_BOXES) { | |
if (event.offsetX >= box.x && event.offsetX <= box.x2 && | |
event.offsetY >= box.y && event.offsetY <= box.y2) { | |
return box; | |
} | |
} | |
} | |
function pipeline_mousemove(event) { | |
// Highlight dependency lines on mouse hover. | |
let box = pipeline_mouse_hit(event); | |
if (box) { | |
if (box.i != LAST_HOVER) { | |
LAST_HOVER = box.i; | |
let g = document.getElementById('pipeline-graph-lines'); | |
let ctx = g.getContext('2d'); | |
ctx.clearRect(0, 0, g.width, g.height); | |
ctx.save(); | |
ctx.translate(X_LINE, MARGIN); | |
ctx.lineWidth = 2; | |
draw_dep_lines(ctx, box.i, true); | |
if (box.i in REVERSE_UNIT_DEPS) { | |
const dep_unit = REVERSE_UNIT_DEPS[box.i]; | |
if (dep_unit in UNIT_COORDS) { | |
const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; | |
draw_one_dep_line(ctx, x, y, box.i, true); | |
} | |
} | |
if (box.i in REVERSE_UNIT_RMETA_DEPS) { | |
const dep_unit = REVERSE_UNIT_RMETA_DEPS[box.i]; | |
if (dep_unit in UNIT_COORDS) { | |
const {x, y, rmeta_x} = UNIT_COORDS[dep_unit]; | |
draw_one_dep_line(ctx, rmeta_x, y, box.i, true); | |
} | |
} | |
ctx.restore(); | |
} | |
} | |
} | |
render_pipeline_graph(); | |
render_timing_graph(); | |
// Set up and handle controls. | |
{ | |
const range = document.getElementById('min-unit-time'); | |
const time_output = document.getElementById('min-unit-time-output'); | |
time_output.innerHTML = `${range.value}s`; | |
range.oninput = event => { | |
time_output.innerHTML = `${range.value}s`; | |
render_pipeline_graph(); | |
}; | |
const scale = document.getElementById('scale'); | |
const scale_output = document.getElementById('scale-output'); | |
scale_output.innerHTML = `${scale.value}`; | |
scale.oninput = event => { | |
scale_output.innerHTML = `${scale.value}`; | |
render_pipeline_graph(); | |
render_timing_graph(); | |
}; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment