Deployed f54f3cc
to dev with MkDocs 1.6.1 and mike 2.1.3
|
@ -47,4 +47,9 @@ html[data-theme="dark"] {
|
||||||
.pyodide-clickable {
|
.pyodide-clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For themes other than Material. */
|
||||||
|
.pyodide .twemoji svg {
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,28 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Backlinks crumb separator. */
|
||||||
|
.doc-backlink-crumb {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: .2rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.doc-backlink-crumb:not(:first-child)::before {
|
||||||
|
background-color: var(--md-default-fg-color--lighter);
|
||||||
|
content: "";
|
||||||
|
display: inline;
|
||||||
|
height: 1rem;
|
||||||
|
--md-path-icon: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6z"/></svg>');
|
||||||
|
-webkit-mask-image: var(--md-path-icon);
|
||||||
|
mask-image: var(--md-path-icon);
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
.doc-backlink-crumb.last {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* Symbols in Navigation and ToC. */
|
/* Symbols in Navigation and ToC. */
|
||||||
:root, :host,
|
:root, :host,
|
||||||
[data-md-color-scheme="default"] {
|
[data-md-color-scheme="default"] {
|
||||||
|
@ -83,7 +105,8 @@ code.doc-symbol {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-parameter {
|
code.doc-symbol-parameter,
|
||||||
|
a code.doc-symbol-parameter {
|
||||||
color: var(--doc-symbol-parameter-fg-color);
|
color: var(--doc-symbol-parameter-fg-color);
|
||||||
background-color: var(--doc-symbol-parameter-bg-color);
|
background-color: var(--doc-symbol-parameter-bg-color);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +115,8 @@ code.doc-symbol-parameter::after {
|
||||||
content: "param";
|
content: "param";
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-attribute {
|
code.doc-symbol-attribute,
|
||||||
|
a code.doc-symbol-attribute {
|
||||||
color: var(--doc-symbol-attribute-fg-color);
|
color: var(--doc-symbol-attribute-fg-color);
|
||||||
background-color: var(--doc-symbol-attribute-bg-color);
|
background-color: var(--doc-symbol-attribute-bg-color);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +125,8 @@ code.doc-symbol-attribute::after {
|
||||||
content: "attr";
|
content: "attr";
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-function {
|
code.doc-symbol-function,
|
||||||
|
a code.doc-symbol-function {
|
||||||
color: var(--doc-symbol-function-fg-color);
|
color: var(--doc-symbol-function-fg-color);
|
||||||
background-color: var(--doc-symbol-function-bg-color);
|
background-color: var(--doc-symbol-function-bg-color);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +135,8 @@ code.doc-symbol-function::after {
|
||||||
content: "func";
|
content: "func";
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-method {
|
code.doc-symbol-method,
|
||||||
|
a code.doc-symbol-method {
|
||||||
color: var(--doc-symbol-method-fg-color);
|
color: var(--doc-symbol-method-fg-color);
|
||||||
background-color: var(--doc-symbol-method-bg-color);
|
background-color: var(--doc-symbol-method-bg-color);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +145,8 @@ code.doc-symbol-method::after {
|
||||||
content: "meth";
|
content: "meth";
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-class {
|
code.doc-symbol-class,
|
||||||
|
a code.doc-symbol-class {
|
||||||
color: var(--doc-symbol-class-fg-color);
|
color: var(--doc-symbol-class-fg-color);
|
||||||
background-color: var(--doc-symbol-class-bg-color);
|
background-color: var(--doc-symbol-class-bg-color);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +155,8 @@ code.doc-symbol-class::after {
|
||||||
content: "class";
|
content: "class";
|
||||||
}
|
}
|
||||||
|
|
||||||
code.doc-symbol-module {
|
code.doc-symbol-module,
|
||||||
|
a code.doc-symbol-module {
|
||||||
color: var(--doc-symbol-module-fg-color);
|
color: var(--doc-symbol-module-fg-color);
|
||||||
background-color: var(--doc-symbol-module-bg-color);
|
background-color: var(--doc-symbol-module-bg-color);
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 32 KiB |
BIN
dev/assets/images/social/concepts/advanced/extensions.png
Normal file
After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
BIN
dev/assets/images/social/concepts/advanced/testing.png
Normal file
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 39 KiB |
BIN
dev/assets/images/social/overview/performance.png
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
BIN
dev/assets/images/social/reference/extension_hooks.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
dev/assets/images/social/reference/testing_api.png
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
16
dev/assets/javascripts/bundle.c8b220af.min.js
vendored
Normal file
7
dev/assets/javascripts/bundle.c8b220af.min.js.map
Normal file
16
dev/assets/javascripts/bundle.f1b6f286.min.js
vendored
1
dev/assets/stylesheets/main.4af4bdda.min.css
vendored
Normal file
1
dev/assets/stylesheets/main.8608ea7d.min.css
vendored
161
dev/benchmarks/asv.css
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/* Basic navigation */
|
||||||
|
|
||||||
|
.asv-navigation {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav ul li.active a {
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li.active span.navbar-brand {
|
||||||
|
background-color: #e7e7e7;
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav li.active span.navbar-brand:hover {
|
||||||
|
background-color: #e7e7e7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-link {
|
||||||
|
color: #2458D9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-default>.panel-heading,
|
||||||
|
.panel-heading {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight:bold;
|
||||||
|
padding: 2px;
|
||||||
|
text-align: center;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn,
|
||||||
|
.btn-group,
|
||||||
|
.btn-group-vertical>.btn:first-child,
|
||||||
|
.btn-group-vertical>.btn:last-child:not(:first-child),
|
||||||
|
.btn-group-vertical>.btn:last-child {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default:focus, .btn-default:active, .btn-default.active {
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #99bfcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#range {
|
||||||
|
font-family: monospace;
|
||||||
|
text-align: center;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-inner {
|
||||||
|
min-width: 100px;
|
||||||
|
max-width: 800px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Benchmark tree */
|
||||||
|
|
||||||
|
.nav-list {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list>li {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list>li>a {
|
||||||
|
padding: 0;
|
||||||
|
padding-left: 5px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list>li>a:focus {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #99bfcd;
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0,0,0,.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list>li>.nav-header {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caret-right {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
margin-left: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-left: 4px solid;
|
||||||
|
border-bottom: 4px solid transparent;
|
||||||
|
border-top: 4px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Summary page */
|
||||||
|
|
||||||
|
.benchmark-group > h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-container {
|
||||||
|
width: 300px;
|
||||||
|
height: 116px;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-container:hover {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-plot {
|
||||||
|
width: 292px;
|
||||||
|
height: 88px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benchmark-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #000;
|
||||||
|
width: 292px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extra-buttons {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extra-buttons a {
|
||||||
|
border: solid 1px #ccc;
|
||||||
|
}
|
525
dev/benchmarks/asv.js
Normal file
|
@ -0,0 +1,525 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
/* GLOBAL STATE */
|
||||||
|
/* The index.json content as returned from the server */
|
||||||
|
var main_timestamp = '';
|
||||||
|
var main_json = {};
|
||||||
|
/* Extra pages: {name: show_function} */
|
||||||
|
var loaded_pages = {};
|
||||||
|
/* Previous window scroll positions */
|
||||||
|
var window_scroll_positions = {};
|
||||||
|
/* Previous window hash location */
|
||||||
|
var window_last_location = null;
|
||||||
|
/* Graph data cache */
|
||||||
|
var graph_cache = {};
|
||||||
|
var graph_cache_max_size = 5;
|
||||||
|
|
||||||
|
var colors = [
|
||||||
|
'#247AAD',
|
||||||
|
'#E24A33',
|
||||||
|
'#988ED5',
|
||||||
|
'#777777',
|
||||||
|
'#FBC15E',
|
||||||
|
'#8EBA42',
|
||||||
|
'#FFB5B8'
|
||||||
|
];
|
||||||
|
|
||||||
|
var time_units = [
|
||||||
|
['ps', 'picoseconds', 0.000000000001],
|
||||||
|
['ns', 'nanoseconds', 0.000000001],
|
||||||
|
['μs', 'microseconds', 0.000001],
|
||||||
|
['ms', 'milliseconds', 0.001],
|
||||||
|
['s', 'seconds', 1],
|
||||||
|
['m', 'minutes', 60],
|
||||||
|
['h', 'hours', 60 * 60],
|
||||||
|
['d', 'days', 60 * 60 * 24],
|
||||||
|
['w', 'weeks', 60 * 60 * 24 * 7],
|
||||||
|
['y', 'years', 60 * 60 * 24 * 7 * 52],
|
||||||
|
['C', 'centuries', 60 * 60 * 24 * 7 * 52 * 100]
|
||||||
|
];
|
||||||
|
|
||||||
|
var mem_units = [
|
||||||
|
['', 'bytes', 1],
|
||||||
|
['k', 'kilobytes', 1000],
|
||||||
|
['M', 'megabytes', 1000000],
|
||||||
|
['G', 'gigabytes', 1000000000],
|
||||||
|
['T', 'terabytes', 1000000000000]
|
||||||
|
];
|
||||||
|
|
||||||
|
function pretty_second(x) {
|
||||||
|
for (var i = 0; i < time_units.length - 1; ++i) {
|
||||||
|
if (Math.abs(x) < time_units[i+1][2]) {
|
||||||
|
return (x / time_units[i][2]).toFixed(3) + time_units[i][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'inf';
|
||||||
|
}
|
||||||
|
|
||||||
|
function pretty_byte(x) {
|
||||||
|
for (var i = 0; i < mem_units.length - 1; ++i) {
|
||||||
|
if (Math.abs(x) < mem_units[i+1][2]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
return x + '';
|
||||||
|
}
|
||||||
|
return (x / mem_units[i][2]).toFixed(3) + mem_units[i][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function pretty_unit(x, unit) {
|
||||||
|
if (unit == "seconds") {
|
||||||
|
return pretty_second(x);
|
||||||
|
}
|
||||||
|
else if (unit == "bytes") {
|
||||||
|
return pretty_byte(x);
|
||||||
|
}
|
||||||
|
else if (unit && unit != "unit") {
|
||||||
|
return '' + x.toPrecision(3) + ' ' + unit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '' + x.toPrecision(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pad_left(s, c, num) {
|
||||||
|
s = '' + s;
|
||||||
|
while (s.length < num) {
|
||||||
|
s = c + s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_date_yyyymmdd(date) {
|
||||||
|
return (pad_left(date.getFullYear(), '0', 4)
|
||||||
|
+ '-' + pad_left(date.getMonth() + 1, '0', 2)
|
||||||
|
+ '-' + pad_left(date.getDate(), '0', 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_date_yyyymmdd_hhmm(date) {
|
||||||
|
return (format_date_yyyymmdd(date) + ' '
|
||||||
|
+ pad_left(date.getHours(), '0', 2)
|
||||||
|
+ ':' + pad_left(date.getMinutes(), '0', 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a flat index to permutation to the corresponding value */
|
||||||
|
function param_selection_from_flat_idx(params, idx) {
|
||||||
|
var selection = [];
|
||||||
|
if (idx < 0) {
|
||||||
|
idx = 0;
|
||||||
|
}
|
||||||
|
for (var k = params.length-1; k >= 0; --k) {
|
||||||
|
var j = idx % params[k].length;
|
||||||
|
selection.unshift([j]);
|
||||||
|
idx = (idx - j) / params[k].length;
|
||||||
|
}
|
||||||
|
selection.unshift([null]);
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a benchmark parameter value from their native Python
|
||||||
|
repr format to a number or a string, ready for presentation */
|
||||||
|
function convert_benchmark_param_value(value_repr) {
|
||||||
|
var match = Number(value_repr);
|
||||||
|
if (!isNaN(match)) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python str */
|
||||||
|
match = value_repr.match(/^'(.+)'$/);
|
||||||
|
if (match) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python unicode */
|
||||||
|
match = value_repr.match(/^u'(.+)'$/);
|
||||||
|
if (match) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Python class */
|
||||||
|
match = value_repr.match(/^<class '(.+)'>$/);
|
||||||
|
if (match) {
|
||||||
|
return match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return value_repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert loaded graph data to a format flot understands, by
|
||||||
|
treating either time or one of the parameters as x-axis,
|
||||||
|
and selecting only one value of the remaining axes */
|
||||||
|
function filter_graph_data(raw_series, x_axis, other_indices, params) {
|
||||||
|
if (params.length == 0) {
|
||||||
|
/* Simple time series */
|
||||||
|
return raw_series;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute position of data entry in the results list,
|
||||||
|
and stride corresponding to plot x-axis parameter */
|
||||||
|
var stride = 1;
|
||||||
|
var param_stride = 0;
|
||||||
|
var param_idx = 0;
|
||||||
|
for (var k = params.length - 1; k >= 0; --k) {
|
||||||
|
if (k == x_axis - 1) {
|
||||||
|
param_stride = stride;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
param_idx += other_indices[k + 1] * stride;
|
||||||
|
}
|
||||||
|
stride *= params[k].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x_axis == 0) {
|
||||||
|
/* x-axis is time axis */
|
||||||
|
var series = new Array(raw_series.length);
|
||||||
|
for (var k = 0; k < raw_series.length; ++k) {
|
||||||
|
if (raw_series[k][1] === null) {
|
||||||
|
series[k] = [raw_series[k][0], null];
|
||||||
|
} else {
|
||||||
|
series[k] = [raw_series[k][0],
|
||||||
|
raw_series[k][1][param_idx]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* x-axis is some parameter axis */
|
||||||
|
var time_idx = null;
|
||||||
|
if (other_indices[0] === null) {
|
||||||
|
time_idx = raw_series.length - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Need to search for the correct time value */
|
||||||
|
for (var k = 0; k < raw_series.length; ++k) {
|
||||||
|
if (raw_series[k][0] == other_indices[0]) {
|
||||||
|
time_idx = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (time_idx === null) {
|
||||||
|
/* No data points */
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var x_values = params[x_axis - 1];
|
||||||
|
var series = new Array(x_values.length);
|
||||||
|
for (var k = 0; k < x_values.length; ++k) {
|
||||||
|
if (raw_series[time_idx][1] === null) {
|
||||||
|
series[k] = [convert_benchmark_param_value(x_values[k]),
|
||||||
|
null];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
series[k] = [convert_benchmark_param_value(x_values[k]),
|
||||||
|
raw_series[time_idx][1][param_idx]];
|
||||||
|
}
|
||||||
|
param_idx += param_stride;
|
||||||
|
}
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter_graph_data_idx(raw_series, x_axis, flat_idx, params) {
|
||||||
|
var selection = param_selection_from_flat_idx(params, flat_idx);
|
||||||
|
var flat_selection = [];
|
||||||
|
$.each(selection, function(i, v) {
|
||||||
|
flat_selection.push(v[0]);
|
||||||
|
});
|
||||||
|
return filter_graph_data(raw_series, x_axis, flat_selection, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Escape special characters in graph item file names.
|
||||||
|
The implementation must match asv.util.sanitize_filename */
|
||||||
|
function sanitize_filename(name) {
|
||||||
|
var bad_re = /[<>:"\/\\^|?*\x00-\x1f]/g;
|
||||||
|
var bad_names = ["CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3",
|
||||||
|
"COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1",
|
||||||
|
"LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8",
|
||||||
|
"LPT9"];
|
||||||
|
name = name.replace(bad_re, "_");
|
||||||
|
if (bad_names.indexOf(name.toUpperCase()) != -1) {
|
||||||
|
name = name + "_";
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a specific group of parameters, generate the URL to
|
||||||
|
use to load that graph.
|
||||||
|
The implementation must match asv.graph.Graph.get_file_path
|
||||||
|
*/
|
||||||
|
function graph_to_path(benchmark_name, state) {
|
||||||
|
var parts = [];
|
||||||
|
$.each(state, function(key, value) {
|
||||||
|
var part;
|
||||||
|
if (value === null) {
|
||||||
|
part = key + "-null";
|
||||||
|
} else if (value) {
|
||||||
|
part = key + "-" + value;
|
||||||
|
} else {
|
||||||
|
part = key;
|
||||||
|
}
|
||||||
|
parts.push(sanitize_filename('' + part));
|
||||||
|
});
|
||||||
|
parts.sort();
|
||||||
|
parts.splice(0, 0, "graphs");
|
||||||
|
parts.push(sanitize_filename(benchmark_name));
|
||||||
|
|
||||||
|
/* Escape URI components */
|
||||||
|
parts = $.map(parts, function (val) { return encodeURIComponent(val); });
|
||||||
|
return parts.join('/') + ".json";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Load and cache graph data (on javascript side)
|
||||||
|
*/
|
||||||
|
function load_graph_data(url, success, failure) {
|
||||||
|
var dfd = $.Deferred();
|
||||||
|
if (graph_cache[url]) {
|
||||||
|
setTimeout(function() {
|
||||||
|
dfd.resolve(graph_cache[url]);
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$.ajax({
|
||||||
|
url: url + '?timestamp=' + $.asv.main_timestamp,
|
||||||
|
dataType: "json",
|
||||||
|
cache: true
|
||||||
|
}).done(function(data) {
|
||||||
|
if (Object.keys(graph_cache).length > graph_cache_max_size) {
|
||||||
|
$.each(Object.keys(graph_cache), function (i, key) {
|
||||||
|
delete graph_cache[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
graph_cache[url] = data;
|
||||||
|
dfd.resolve(data);
|
||||||
|
}).fail(function() {
|
||||||
|
dfd.reject();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return dfd.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse hash string, assuming format similar to standard URL
|
||||||
|
query strings
|
||||||
|
*/
|
||||||
|
function parse_hash_string(str) {
|
||||||
|
var info = {location: [''], params: {}};
|
||||||
|
|
||||||
|
if (str && str[0] == '#') {
|
||||||
|
str = str.slice(1);
|
||||||
|
}
|
||||||
|
if (str && str[0] == '/') {
|
||||||
|
str = str.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = str.match(/^([^?]*?)\?/);
|
||||||
|
if (match) {
|
||||||
|
info['location'] = decodeURIComponent(match[1]).replace(/\/+/, '/').split('/');
|
||||||
|
var rest = str.slice(match[1].length+1);
|
||||||
|
var parts = rest.split('&');
|
||||||
|
for (var i = 0; i < parts.length; ++i) {
|
||||||
|
var part = parts[i].split('=');
|
||||||
|
if (part.length != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var key = decodeURIComponent(part[0].replace(/\+/g, " "));
|
||||||
|
var value = decodeURIComponent(part[1].replace(/\+/g, " "));
|
||||||
|
if (value == '[none]') {
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
if (info['params'][key] === undefined) {
|
||||||
|
info['params'][key] = [value];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info['params'][key].push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info['location'] = decodeURIComponent(str).replace(/\/+/, '/').split('/');
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generate a hash string, inverse of parse_hash_string
|
||||||
|
*/
|
||||||
|
function format_hash_string(info) {
|
||||||
|
var parts = info['params'];
|
||||||
|
var str = '#' + info['location'];
|
||||||
|
|
||||||
|
if (parts) {
|
||||||
|
str = str + '?';
|
||||||
|
var first = true;
|
||||||
|
$.each(parts, function (key, values) {
|
||||||
|
$.each(values, function (idx, value) {
|
||||||
|
if (!first) {
|
||||||
|
str = str + '&';
|
||||||
|
}
|
||||||
|
if (value === null) {
|
||||||
|
value = '[none]';
|
||||||
|
}
|
||||||
|
str = str + encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
||||||
|
first = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dealing with sub-pages
|
||||||
|
*/
|
||||||
|
|
||||||
|
function show_page(name, params) {
|
||||||
|
if (loaded_pages[name] !== undefined) {
|
||||||
|
$("#nav ul li.active").removeClass('active');
|
||||||
|
$("#nav-li-" + name).addClass('active');
|
||||||
|
$("#graph-display").hide();
|
||||||
|
$("#summarygrid-display").hide();
|
||||||
|
$("#summarylist-display").hide();
|
||||||
|
$('#regressions-display').hide();
|
||||||
|
$('.tooltip').remove();
|
||||||
|
loaded_pages[name](params);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashchange() {
|
||||||
|
var info = parse_hash_string(window.location.hash);
|
||||||
|
|
||||||
|
/* Keep track of window scroll position; makes the back-button work */
|
||||||
|
var old_scroll_pos = window_scroll_positions[info.location.join('/')];
|
||||||
|
window_scroll_positions[window_last_location] = $(window).scrollTop();
|
||||||
|
window_last_location = info.location.join('/');
|
||||||
|
|
||||||
|
/* Redirect to correct handler */
|
||||||
|
if (show_page(info.location, info.params)) {
|
||||||
|
/* show_page does the work */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Display benchmark page */
|
||||||
|
info.params['benchmark'] = info.location[0];
|
||||||
|
show_page('graphdisplay', info.params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scroll back to previous position, if any */
|
||||||
|
if (old_scroll_pos !== undefined) {
|
||||||
|
$(window).scrollTop(old_scroll_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_commit_hash(revision) {
|
||||||
|
var commit_hash = main_json.revision_to_hash[revision];
|
||||||
|
if (commit_hash) {
|
||||||
|
// Return printable commit hash
|
||||||
|
commit_hash = commit_hash.slice(0, main_json.hash_length);
|
||||||
|
}
|
||||||
|
return commit_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_revision(commit_hash) {
|
||||||
|
var rev = null;
|
||||||
|
$.each(main_json.revision_to_hash, function(revision, full_commit_hash) {
|
||||||
|
if (full_commit_hash.startsWith(commit_hash)) {
|
||||||
|
rev = revision;
|
||||||
|
// break the $.each loop
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return rev;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init_index() {
|
||||||
|
/* Fetch the main index.json and then set up the page elements
|
||||||
|
based on it. */
|
||||||
|
$.ajax({
|
||||||
|
url: "index.json" + '?timestamp=' + $.asv.main_timestamp,
|
||||||
|
dataType: "json",
|
||||||
|
cache: true
|
||||||
|
}).done(function (index) {
|
||||||
|
main_json = index;
|
||||||
|
$.asv.main_json = index;
|
||||||
|
|
||||||
|
/* Page title */
|
||||||
|
var project_name = $("#project-name")[0];
|
||||||
|
project_name.textContent = index.project;
|
||||||
|
project_name.setAttribute("href", index.project_url);
|
||||||
|
$("#project-name").textContent = index.project;
|
||||||
|
document.title = "airspeed velocity of an unladen " + index.project;
|
||||||
|
|
||||||
|
$(window).on('hashchange', hashchange);
|
||||||
|
|
||||||
|
$('#graph-display').hide();
|
||||||
|
$('#regressions-display').hide();
|
||||||
|
$('#summarygrid-display').hide();
|
||||||
|
$('#summarylist-display').hide();
|
||||||
|
|
||||||
|
hashchange();
|
||||||
|
}).fail(function () {
|
||||||
|
$.asv.ui.network_error();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
/* Fetch the info.json */
|
||||||
|
$.ajax({
|
||||||
|
url: "info.json",
|
||||||
|
dataType: "json",
|
||||||
|
cache: false
|
||||||
|
}).done(function (info) {
|
||||||
|
main_timestamp = info['timestamp'];
|
||||||
|
$.asv.main_timestamp = main_timestamp;
|
||||||
|
init_index();
|
||||||
|
}).fail(function () {
|
||||||
|
$.asv.ui.network_error();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set up $.asv
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.register_page = function(name, show_function) {
|
||||||
|
loaded_pages[name] = show_function;
|
||||||
|
}
|
||||||
|
this.parse_hash_string = parse_hash_string;
|
||||||
|
this.format_hash_string = format_hash_string;
|
||||||
|
|
||||||
|
this.filter_graph_data = filter_graph_data;
|
||||||
|
this.filter_graph_data_idx = filter_graph_data_idx;
|
||||||
|
this.convert_benchmark_param_value = convert_benchmark_param_value;
|
||||||
|
this.param_selection_from_flat_idx = param_selection_from_flat_idx;
|
||||||
|
this.graph_to_path = graph_to_path;
|
||||||
|
this.load_graph_data = load_graph_data;
|
||||||
|
this.get_commit_hash = get_commit_hash;
|
||||||
|
this.get_revision = get_revision;
|
||||||
|
|
||||||
|
this.main_timestamp = main_timestamp; /* Updated after info.json loads */
|
||||||
|
this.main_json = main_json; /* Updated after index.json loads */
|
||||||
|
|
||||||
|
this.format_date_yyyymmdd = format_date_yyyymmdd;
|
||||||
|
this.format_date_yyyymmdd_hhmm = format_date_yyyymmdd_hhmm;
|
||||||
|
this.pretty_unit = pretty_unit;
|
||||||
|
this.time_units = time_units;
|
||||||
|
this.mem_units = mem_units;
|
||||||
|
|
||||||
|
this.colors = colors;
|
||||||
|
|
||||||
|
$.asv = this;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Launch it
|
||||||
|
*/
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
231
dev/benchmarks/asv_ui.js
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
function make_panel(nav, heading) {
|
||||||
|
var panel = $('<div class="panel panel-default"/>');
|
||||||
|
nav.append(panel);
|
||||||
|
var panel_header = $(
|
||||||
|
'<div class="panel-heading">' + heading + '</div>');
|
||||||
|
panel.append(panel_header);
|
||||||
|
var panel_body = $('<div class="panel-body"/>');
|
||||||
|
panel.append(panel_body);
|
||||||
|
return panel_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_value_selector_panel(nav, heading, values, setup_callback) {
|
||||||
|
var panel_body = make_panel(nav, heading);
|
||||||
|
var vertical = false;
|
||||||
|
var buttons = $('<div class="btn-group" ' +
|
||||||
|
'data-toggle="buttons"/>');
|
||||||
|
|
||||||
|
panel_body.append(buttons);
|
||||||
|
|
||||||
|
$.each(values, function (idx, value) {
|
||||||
|
var button = $(
|
||||||
|
'<a class="btn btn-default btn-xs active" role="button"/>');
|
||||||
|
setup_callback(idx, value, button);
|
||||||
|
buttons.append(button);
|
||||||
|
});
|
||||||
|
|
||||||
|
return panel_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reflow_value_selector_panels(no_timeout) {
|
||||||
|
$('.panel').each(function (i, panel_obj) {
|
||||||
|
var panel = $(panel_obj);
|
||||||
|
panel.find('.btn-group').each(function (i, buttons_obj) {
|
||||||
|
var buttons = $(buttons_obj);
|
||||||
|
var width = 0;
|
||||||
|
|
||||||
|
if (buttons.hasClass('reflow-done')) {
|
||||||
|
/* already processed */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(buttons.children(), function(idx, value) {
|
||||||
|
width += value.scrollWidth;
|
||||||
|
});
|
||||||
|
|
||||||
|
var max_width = panel_obj.clientWidth;
|
||||||
|
|
||||||
|
if (width >= max_width) {
|
||||||
|
buttons.addClass("btn-group-vertical");
|
||||||
|
buttons.css("width", "100%");
|
||||||
|
buttons.css("max-height", "20ex");
|
||||||
|
buttons.css("overflow-y", "auto");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buttons.addClass("btn-group-justified");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The widths can be zero if the UI is not fully layouted yet,
|
||||||
|
so mark the adjustment complete only if this is not the case */
|
||||||
|
if (width > 0 && max_width > 0) {
|
||||||
|
buttons.addClass("reflow-done");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!no_timeout) {
|
||||||
|
/* Call again asynchronously, in case the UI was not fully layouted yet */
|
||||||
|
setTimeout(function() { $.asv.ui.reflow_value_selector_panels(true); }, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function network_error(ajax, status, error) {
|
||||||
|
$("#error-message").text(
|
||||||
|
"Error fetching content. " +
|
||||||
|
"Perhaps web server has gone down.");
|
||||||
|
$("#error").modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hover_graph(element, graph_url, benchmark_basename, parameter_idx, revisions) {
|
||||||
|
/* Show the summary graph as a popup */
|
||||||
|
var plot_div = $('<div/>');
|
||||||
|
plot_div.css('width', '11.8em');
|
||||||
|
plot_div.css('height', '7em');
|
||||||
|
plot_div.css('border', '2px solid black');
|
||||||
|
plot_div.css('background-color', 'white');
|
||||||
|
|
||||||
|
function update_plot() {
|
||||||
|
var markings = [];
|
||||||
|
|
||||||
|
if (revisions) {
|
||||||
|
$.each(revisions, function(i, revs) {
|
||||||
|
var rev_a = revs[0];
|
||||||
|
var rev_b = revs[1];
|
||||||
|
|
||||||
|
if (rev_a !== null) {
|
||||||
|
markings.push({ color: '#d00', lineWidth: 2, xaxis: { from: rev_a, to: rev_a }});
|
||||||
|
markings.push({ color: "rgba(255,0,0,0.1)", xaxis: { from: rev_a, to: rev_b }});
|
||||||
|
}
|
||||||
|
markings.push({ color: '#d00', lineWidth: 2, xaxis: { from: rev_b, to: rev_b }});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.asv.load_graph_data(
|
||||||
|
graph_url
|
||||||
|
).done(function (data) {
|
||||||
|
var params = $.asv.main_json.benchmarks[benchmark_basename].params;
|
||||||
|
data = $.asv.filter_graph_data_idx(data, 0, parameter_idx, params);
|
||||||
|
var options = {
|
||||||
|
colors: ['#000'],
|
||||||
|
series: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
lineWidth: 2
|
||||||
|
},
|
||||||
|
shadowSize: 0
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
borderWidth: 1,
|
||||||
|
margin: 0,
|
||||||
|
labelMargin: 0,
|
||||||
|
axisMargin: 0,
|
||||||
|
minBorderMargin: 0,
|
||||||
|
markings: markings,
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
ticks: [],
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
ticks: [],
|
||||||
|
min: 0
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var plot = $.plot(plot_div, [{data: data}], options);
|
||||||
|
}).fail(function () {
|
||||||
|
// TODO: Handle failure
|
||||||
|
});
|
||||||
|
|
||||||
|
return plot_div;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.popover({
|
||||||
|
placement: 'left auto',
|
||||||
|
trigger: 'hover',
|
||||||
|
html: true,
|
||||||
|
delay: 50,
|
||||||
|
content: $('<div/>').append(plot_div)
|
||||||
|
});
|
||||||
|
|
||||||
|
element.on('show.bs.popover', update_plot);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hover_summary_graph(element, benchmark_basename) {
|
||||||
|
/* Show the summary graph as a popup */
|
||||||
|
var plot_div = $('<div/>');
|
||||||
|
plot_div.css('width', '11.8em');
|
||||||
|
plot_div.css('height', '7em');
|
||||||
|
plot_div.css('border', '2px solid black');
|
||||||
|
plot_div.css('background-color', 'white');
|
||||||
|
|
||||||
|
function update_plot() {
|
||||||
|
var markings = [];
|
||||||
|
|
||||||
|
$.asv.load_graph_data(
|
||||||
|
'graphs/summary/' + benchmark_basename + '.json'
|
||||||
|
).done(function (data) {
|
||||||
|
var options = {
|
||||||
|
colors: $.asv.colors,
|
||||||
|
series: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
lineWidth: 2
|
||||||
|
},
|
||||||
|
shadowSize: 0
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
borderWidth: 1,
|
||||||
|
margin: 0,
|
||||||
|
labelMargin: 0,
|
||||||
|
axisMargin: 0,
|
||||||
|
minBorderMargin: 0,
|
||||||
|
markings: markings,
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
ticks: [],
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
ticks: [],
|
||||||
|
min: 0
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var plot = $.plot(plot_div, [{data: data}], options);
|
||||||
|
}).fail(function () {
|
||||||
|
// TODO: Handle failure
|
||||||
|
});
|
||||||
|
|
||||||
|
return plot_div;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.popover({
|
||||||
|
placement: 'left auto',
|
||||||
|
trigger: 'hover',
|
||||||
|
html: true,
|
||||||
|
delay: 50,
|
||||||
|
content: $('<div/>').append(plot_div)
|
||||||
|
});
|
||||||
|
|
||||||
|
element.on('show.bs.popover', update_plot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set up $.asv.ui
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.network_error = network_error;
|
||||||
|
this.make_panel = make_panel;
|
||||||
|
this.make_value_selector_panel = make_value_selector_panel;
|
||||||
|
this.reflow_value_selector_panels = reflow_value_selector_panels;
|
||||||
|
this.hover_graph = hover_graph;
|
||||||
|
this.hover_summary_graph = hover_summary_graph;
|
||||||
|
|
||||||
|
$.asv.ui = this;
|
||||||
|
});
|
23
dev/benchmarks/error.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>airspeed velocity error</title>
|
||||||
|
<link rel="shortcut icon" href="swallow.ico"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<img src="swallow.png" width="22" height="22" alt="swallow"></img>
|
||||||
|
Can not determine continental origin of swallow.
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
One or more external (JavaScript) dependencies of airspeed velocity failed to load.
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Make sure you have an active internet connection and enable 3rd-party scripts
|
||||||
|
in your browser the first time you load airspeed velocity.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
1427
dev/benchmarks/graphdisplay.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [52121600.0, 54030336.0]], [1569, [52006912.0, 54030336.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [52129792.0, 54525952.0]], [1569, [52019200.0, 54542336.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [43671552.0, 43925504.0]], [1569, [43667456.0, 43921408.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [43675648.0, 43929600.0]], [1569, [43671552.0, 43925504.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.06844023999997262, 0.25948228500001846]], [1569, [0.0695505670000216, 0.2585547080000197]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.03282115399997565, 0.1461098879999838]], [1569, [0.03280580699998836, 0.14556000400000357]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.0035044859999970868, 0.004806205000022601]], [1569, [0.003512746000012612, 0.004752005000000281]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [9.84330000051159e-05, 0.000542360999986613]], [1569, [9.899399998403169e-05, 0.0005454930000041713]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.21055065100000547, 0.20605139500003133]], [1569, [0.20886826499997824, 0.20461195600000792]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.19086866300000338], [1569, 0.1891247499999622]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [54018048.0, 53542912.0]], [1569, [53940224.0, 53530624.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [54571008.0, 54530048.0]], [1569, [54566912.0, 54525952.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [43925504.0, 43925504.0]], [1569, [43921408.0, 43687936.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [43929600.0, 43929600.0]], [1569, [43925504.0, 43925504.0]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.2582084590000022, 0.2630794039999955]], [1569, [0.2609166309999864, 0.26201485799998636]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.14612163999998984, 0.15001642000004267]], [1569, [0.14627813999999262, 0.15037803699999586]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.004762013999993542, 0.004786298999988503]], [1569, [0.004790214000024662, 0.004819428000018888]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.0005448759999922004, 0.0005334049999987656]], [1569, [0.0005436999999801628, 0.0005416959999706705]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, [0.2058522649999759, 0.2053180329999691]], [1569, [0.20448447999996233, 0.2037191150000126]]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 53067386.97974115], [1569, 53008970.27562818]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 53314412.08868371], [1569, 53265830.36855053]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 43798343.942005485], [1569, 43794247.92479085]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 43802439.95921688], [1569, 43798343.942005485]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.13326301010086242], [1569, 0.13409931596367813]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.06924951360815947], [1569, 0.06910291888293614]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.0041040563026955666], [1569, 0.0040856561964745545]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.00023105458297652734], [1569, 0.00023238014982717938]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.20828887477903343], [1569, 0.20672915674372966]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.19086866300000338], [1569, 0.1891247499999622]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 53779955.28517828], [1569, 53735033.72493383]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 54550524.155578785], [1569, 54546428.1552901]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 43925504.00000001], [1569, 43804516.45360199]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 43929599.99999999], [1569, 43925504.00000001]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.2606325526511949], [1569, 0.26146516789296487]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.14805622350084952], [1569, 0.1483139223040422]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.004774141058462804], [1569, 0.004804798796807347]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.0005391099913516415], [1569, 0.0005426970749629188]]
|
|
@ -0,0 +1 @@
|
||||||
|
[[1566, 0.20558497546849924], [1569, 0.20410143874267547]]
|
161
dev/benchmarks/index.html
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>airspeed velocity</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function js_load_failure() {
|
||||||
|
window.location = "error.html";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js" integrity="sha512-eO1AKNIv7KSFl5n81oHCKnYLMi8UV4wWD1TcLYKNTssoECDuiGhoRsQkdiZkl8VUjoms2SeJY7zTSw5noGSqbQ==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.time.min.js" integrity="sha512-lcRowrkiQvFli9HkuJ2Yr58iEwAtzhFNJ1Galsko4SJDhcZfUub8UxGlMQIsMvARiTqx2pm7g6COxJozihOixA==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.selection.min.js" integrity="sha512-3EUG0t3qfbLaGN3FXO86i+57nvxHOXvIb/xMSKRrCuX/HXdn1bkbqwAeLd6U1PDmuEB2cnKhfM+SGLAVQbyjWQ==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.categories.min.js" integrity="sha512-x4QGSZkQ57pNuICMFFevIhDer5NVB5eJCRmENlCdJukMs8xWFH8OHfzWQVSkl9VQ4+4upPPTkHSAewR6KNMjGA==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script language="javascript" type="text/javascript" src="jquery.flot.axislabels.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/flot-orderbars@1.0.0/js/jquery.flot.orderBars.js" integrity="sha256-OXNbT0b5b/TgglckAfR8VaJ2ezZv0dHoIeRKjYMKEr8=" crossorigin="anonymous" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/stupidtable/1.0.1/stupidtable.min.js" integrity="sha512-GM3Ds3dUrgkpKVXc+4RxKbQDoeTemdlzXxn5d/QCOJT6EFdEufu1UTVBpIFDLd6YjIhSThNe+zpo1mwqzNq4GQ==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.19.0/js/md5.min.js" integrity="sha512-8pbzenDolL1l5OPSsoURCx9TEdMFTaeFipASVrMYKhuYtly+k3tcsQYliOEKTmuB1t7yuzAiVo+yd7SJz+ijFQ==" crossorigin="anonymous" referrerpolicy="no-referrer" onerror="js_load_failure()"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.1.1/dist/js/bootstrap.min.js" integrity="sha256-iY0FoX8s/FEg3c26R6iFw3jAtGbzDwcA5QJ1fiS0A6E=" crossorigin="anonymous" onerror="js_load_failure()"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.1.1/dist/css/bootstrap.min.css" integrity="sha256-6VA0SGkrc43SYPvX98q/LhHwm2APqX5us6Vuulsafps=" crossorigin="anonymous">
|
||||||
|
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="asv.js">
|
||||||
|
</script>
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="asv_ui.js">
|
||||||
|
</script>
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="summarygrid.js">
|
||||||
|
</script>
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="summarylist.js">
|
||||||
|
</script>
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="graphdisplay.js">
|
||||||
|
</script>
|
||||||
|
<script language="javascript" type="text/javascript"
|
||||||
|
src="regressions.js">
|
||||||
|
</script>
|
||||||
|
<link href="asv.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="regressions.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="summarylist.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<link rel="shortcut icon" href="swallow.ico"/>
|
||||||
|
<link rel="alternate" type="application/atom+xml" title="Regressions" href="regressions.xml"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav id="nav" class="navbar navbar-left navbar-default navbar-fixed-top" role="navigation">
|
||||||
|
<ul class="nav navbar-nav navbar-left">
|
||||||
|
<li>
|
||||||
|
<p class="navbar-text">
|
||||||
|
<a href="http://github.com/airspeed-velocity/asv/" class="navbar-link" target="_blank"><img src="swallow.png" width="22" height="22" alt="swallow"></img>airspeed velocity</a>
|
||||||
|
of an unladen
|
||||||
|
<a id="project-name" href="#" class="navbar-link" target="_blank">project</a>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li id="nav-li-" class="active"><a href="#/">Benchmark grid</a></li>
|
||||||
|
<li id="nav-li-summarylist"><a href="#/summarylist">Benchmark list</a></li>
|
||||||
|
<li id="nav-li-regressions"><a href="#/regressions">Regressions</a></li>
|
||||||
|
<li id="nav-li-graphdisplay">
|
||||||
|
<span class="navbar-brand" id="title">
|
||||||
|
benchmark
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<div id="summarygrid-display" style="position: absolute; left: 0; top: 55px; width: 100%; height: 100%">
|
||||||
|
</div>
|
||||||
|
<div id="summarylist-display" style="width: 100%; height: 100%">
|
||||||
|
<div id="summarylist-navigation" class="asv-navigation" style="position: absolute; left: 0; top: 55px; bottom: 0; width: 200px; overflow-y: scroll">
|
||||||
|
</div>
|
||||||
|
<div id="summarylist-body" style="position: absolute; left: 200px; top: 55px; bottom: 0px; right: 0px; overflow-y: scroll;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="graph-display" style="width: 100%; height: 100%;">
|
||||||
|
<div id="graphdisplay-navigation" class="asv-navigation" style="position: absolute; left: 0; top: 55px; bottom: 0; width: 200px; overflow-y: scroll">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
commits
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<input id="range" type="text" class="form-control" size="24" readonly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
plot settings
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="btn-group-vertical" style="width: 100%" data-toggle="buttons">
|
||||||
|
<a id="log-scale" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Use a logarithmic scale on the y-axis">
|
||||||
|
log scale
|
||||||
|
</a>
|
||||||
|
<a id="zoom-y-axis" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Zoom y axis to the range of the data, rather than down to zero.">
|
||||||
|
zoom <i>y</i> axis
|
||||||
|
</a>
|
||||||
|
<a id="reference" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Select a reference point">
|
||||||
|
reference
|
||||||
|
</a>
|
||||||
|
<a id="even-spacing" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Space commits evenly, rather than by revision, along the x-axis">
|
||||||
|
even commit spacing
|
||||||
|
</a>
|
||||||
|
<a id="date-scale" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Space commits by commit date along the x-axis">
|
||||||
|
date scale
|
||||||
|
</a>
|
||||||
|
<a id="show-legend" class="btn btn-default btn-xs" role="button"
|
||||||
|
data-toggle="tooltip" data-placement="right"
|
||||||
|
title="Show legend in the graph">
|
||||||
|
legend
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; left: 220px; top: 60px; bottom: 10px; right: 20px;">
|
||||||
|
<div id="graph">
|
||||||
|
<div style="position: absolute; top: 48px; left: 0; right: 0; bottom: 100px;">
|
||||||
|
<div id="main-graph" style="min-height: 100px; width: 100%; height: 100%"></div>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; height: 100px; left: 0; right: 0; bottom: 0; padding-top: 24px">
|
||||||
|
<div id="overview" style="min-height: 100px; width: 100%; height: 100%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="regressions-display" style="position: absolute; left: 0; top: 55px; width: 100%; height: 100%">
|
||||||
|
<div id="regressions-body">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- A modal dialog box for displaying error messages -->
|
||||||
|
<div class="modal fade" id="error" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title alert alert-danger" id="myModalLabel">Error</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="error-message">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
1
dev/benchmarks/index.json
Normal file
4
dev/benchmarks/info.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"asv-version": "0.6.4",
|
||||||
|
"timestamp": 1740214032970
|
||||||
|
}
|
140
dev/benchmarks/jquery.flot.axislabels.js
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
CAxis Labels Plugin for flot. :P
|
||||||
|
Copyright (c) 2010 Xuan Luo
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
(function ($) {
|
||||||
|
var options = { };
|
||||||
|
|
||||||
|
function init(plot) {
|
||||||
|
// This is kind of a hack. There are no hooks in Flot between
|
||||||
|
// the creation and measuring of the ticks (setTicks, measureTickLabels
|
||||||
|
// in setupGrid() ) and the drawing of the ticks and plot box
|
||||||
|
// (insertAxisLabels in setupGrid() ).
|
||||||
|
//
|
||||||
|
// Therefore, we use a trick where we run the draw routine twice:
|
||||||
|
// the first time to get the tick measurements, so that we can change
|
||||||
|
// them, and then have it draw it again.
|
||||||
|
var secondPass = false;
|
||||||
|
plot.hooks.draw.push(function (plot, ctx) {
|
||||||
|
if (!secondPass) {
|
||||||
|
// MEASURE AND SET OPTIONS
|
||||||
|
$.each(plot.getAxes(), function(axisName, axis) {
|
||||||
|
var opts = axis.options // Flot 0.7
|
||||||
|
|| plot.getOptions()[axisName]; // Flot 0.6
|
||||||
|
if (!opts || !opts.axisLabel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var w, h;
|
||||||
|
if (opts.axisLabelUseCanvas != false)
|
||||||
|
opts.axisLabelUseCanvas = true;
|
||||||
|
|
||||||
|
if (opts.axisLabelUseCanvas) {
|
||||||
|
// canvas text
|
||||||
|
if (!opts.axisLabelFontSizePixels)
|
||||||
|
opts.axisLabelFontSizePixels = 14;
|
||||||
|
if (!opts.axisLabelFontFamily)
|
||||||
|
opts.axisLabelFontFamily = 'sans-serif';
|
||||||
|
// since we currently always display x as horiz.
|
||||||
|
// and y as vertical, we only care about the height
|
||||||
|
w = opts.axisLabelFontSizePixels;
|
||||||
|
h = opts.axisLabelFontSizePixels;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// HTML text
|
||||||
|
var elem = $('<div class="axisLabels" style="position:absolute;">' + opts.axisLabel + '</div>');
|
||||||
|
plot.getPlaceholder().append(elem);
|
||||||
|
w = elem.outerWidth(true);
|
||||||
|
h = elem.outerHeight(true);
|
||||||
|
elem.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axisName.charAt(0) == 'x')
|
||||||
|
axis.labelHeight += h;
|
||||||
|
else
|
||||||
|
axis.labelWidth += w;
|
||||||
|
opts.labelHeight = axis.labelHeight;
|
||||||
|
opts.labelWidth = axis.labelWidth;
|
||||||
|
});
|
||||||
|
// re-draw with new label widths and heights
|
||||||
|
secondPass = true;
|
||||||
|
plot.setupGrid();
|
||||||
|
plot.draw();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// DRAW
|
||||||
|
$.each(plot.getAxes(), function(axisName, axis) {
|
||||||
|
var opts = axis.options // Flot 0.7
|
||||||
|
|| plot.getOptions()[axisName]; // Flot 0.6
|
||||||
|
if (!opts || !opts.axisLabel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (opts.axisLabelUseCanvas) {
|
||||||
|
// canvas text
|
||||||
|
var ctx = plot.getCanvas().getContext('2d');
|
||||||
|
ctx.save();
|
||||||
|
ctx.font = opts.axisLabelFontSizePixels + 'px ' +
|
||||||
|
opts.axisLabelFontFamily;
|
||||||
|
var width = ctx.measureText(opts.axisLabel).width;
|
||||||
|
var height = opts.axisLabelFontSizePixels;
|
||||||
|
var x, y;
|
||||||
|
if (axisName.charAt(0) == 'x') {
|
||||||
|
x = plot.getPlotOffset().left + plot.width()/2 - width/2;
|
||||||
|
y = plot.getCanvas().height;
|
||||||
|
} else {
|
||||||
|
x = height * 0.72;
|
||||||
|
y = plot.getPlotOffset().top + plot.height()/2 - width/2;
|
||||||
|
}
|
||||||
|
ctx.translate(x, y);
|
||||||
|
ctx.rotate((axisName.charAt(0) == 'x') ? 0 : -Math.PI/2);
|
||||||
|
ctx.fillText(opts.axisLabel, 0, 0);
|
||||||
|
ctx.restore();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// HTML text
|
||||||
|
plot.getPlaceholder().find('#' + axisName + 'Label').remove();
|
||||||
|
var elem = $('<div id="' + axisName + 'Label" " class="axisLabels" style="position:absolute;">' + opts.axisLabel + '</div>');
|
||||||
|
if (axisName.charAt(0) == 'x') {
|
||||||
|
elem.css('left', plot.getPlotOffset().left + plot.width()/2 - elem.outerWidth()/2 + 'px');
|
||||||
|
elem.css('bottom', '0px');
|
||||||
|
} else {
|
||||||
|
elem.css('top', plot.getPlotOffset().top + plot.height()/2 - elem.outerHeight()/2 + 'px');
|
||||||
|
elem.css('left', '0px');
|
||||||
|
}
|
||||||
|
plot.getPlaceholder().append(elem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
secondPass = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'axisLabels',
|
||||||
|
version: '1.0'
|
||||||
|
});
|
||||||
|
})(jQuery);
|
44
dev/benchmarks/regressions.css
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#regressions-body {
|
||||||
|
margin-left: 2em;
|
||||||
|
margin-right: 2em;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table thead th {
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table thead th.desc:after {
|
||||||
|
content: ' \2191';
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table thead th.asc:after {
|
||||||
|
content: ' \2193';
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table.ignored {
|
||||||
|
padding-top: 1em;
|
||||||
|
color: #ccc;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table.ignored a {
|
||||||
|
color: #82abda;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body .feed-div {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table tbody td.date {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#regressions-body table button {
|
||||||
|
margin-top: -2px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
618
dev/benchmarks/regressions.js
Normal file
|
@ -0,0 +1,618 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
/* Cached contents of downloaded regressions.json */
|
||||||
|
var regression_data = null;
|
||||||
|
/* Current page title */
|
||||||
|
var current_title = "All regressions";
|
||||||
|
/* Whether HTML5 local storage is available */
|
||||||
|
var local_storage_available = false;
|
||||||
|
/* Key prefix for ignored regressions. For each ignored regression,
|
||||||
|
a key "ignore_key_prefix + md5(benchmark_name + date_a + date_b)"
|
||||||
|
is added to HTML5 local storage.
|
||||||
|
*/
|
||||||
|
var ignore_key_prefix = null;
|
||||||
|
/* Set of ignored regressions, same information as in HTML5 local storage.
|
||||||
|
Useful if local storage runs out of space. */
|
||||||
|
var ignored_regressions = {};
|
||||||
|
/* Whether to force reload on next page update */
|
||||||
|
var skip_reload = false;
|
||||||
|
|
||||||
|
function load_data(params) {
|
||||||
|
$("#title").text(current_title);
|
||||||
|
|
||||||
|
if (typeof(Storage) !== "undefined") {
|
||||||
|
/* html5 local storage available */
|
||||||
|
local_storage_available = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regression_data !== null) {
|
||||||
|
// already displayed
|
||||||
|
if (!skip_reload) {
|
||||||
|
var main_div = display_data(regression_data, params);
|
||||||
|
$('#regressions-body').empty();
|
||||||
|
$('#regressions-body').append(main_div);
|
||||||
|
}
|
||||||
|
skip_reload = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var message = $('<div>Loading...</div>');
|
||||||
|
skip_reload = false;
|
||||||
|
$('#regressions-body').append(message);
|
||||||
|
$.ajax({
|
||||||
|
url: 'regressions.json' + '?timestamp=' + $.asv.main_timestamp,
|
||||||
|
dataType: "json",
|
||||||
|
cache: true
|
||||||
|
}).done(function (data) {
|
||||||
|
regression_data = data;
|
||||||
|
var main_div = display_data(data, params);
|
||||||
|
$('#regressions-body').empty();
|
||||||
|
$('#regressions-body').append(main_div);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_url(params, reload) {
|
||||||
|
var info = $.asv.parse_hash_string(window.location.hash);
|
||||||
|
$.each(params || {}, function(key, value) {
|
||||||
|
info.params[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
var new_hash = $.asv.format_hash_string(info);
|
||||||
|
if (new_hash != window.location.hash) {
|
||||||
|
if (reload === undefined) {
|
||||||
|
skip_reload = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skip_reload = !reload;
|
||||||
|
}
|
||||||
|
window.location.hash = new_hash;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skip_reload = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function display_data(data, params) {
|
||||||
|
var main_div = $('<div/>');
|
||||||
|
var branches = $.asv.main_json.params['branch'];
|
||||||
|
var all_ignored_keys = {};
|
||||||
|
|
||||||
|
ignore_key_prefix = 'asv-r-' + $.asv.main_json.project;
|
||||||
|
|
||||||
|
if (branches && branches.length > 1) {
|
||||||
|
/* Add a branch selector */
|
||||||
|
var dropdown_menu = $('<ul class="dropdown-menu" role="menu"/>');
|
||||||
|
var dropdown_div = $('<div class="dropdown">');
|
||||||
|
|
||||||
|
dropdown_div.append($('<button class="btn btn-default dropdown-toggle" data-toggle="dropdown">Branches ' +
|
||||||
|
'<span class="caret"/></button>'));
|
||||||
|
dropdown_div.append(dropdown_menu);
|
||||||
|
|
||||||
|
main_div.append(dropdown_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
var feed_div = $('<div class="feed-div"><a class="btn" href="regressions.xml">Feed (Atom)</a></div>');
|
||||||
|
main_div.append(feed_div);
|
||||||
|
|
||||||
|
var group_div = $('<div>');
|
||||||
|
var group_button = $('<button class="btn btn-small"/>');
|
||||||
|
if (params.grouped) {
|
||||||
|
group_button.text('Ungroup regressions');
|
||||||
|
group_button.on('click', function(evt) {
|
||||||
|
update_url({'grouped': []});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
group_button.text('Group regressions');
|
||||||
|
group_button.on('click', function(evt) {
|
||||||
|
update_url({'grouped': ["true"]});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
group_div.append(group_button);
|
||||||
|
main_div.append(group_div);
|
||||||
|
|
||||||
|
$.each(branches, function(i, branch) {
|
||||||
|
var branch_div = $('<div class="regression-div"/>')
|
||||||
|
|
||||||
|
var display_table = $('<table class="table table-hover"/>');
|
||||||
|
var ignored_table = $('<table class="table table-hover ignored"/>');
|
||||||
|
var ignored_button = $('<button class="btn btn-default">Show ignored regressions...</button>');
|
||||||
|
var ignored_conf_sample_div = $('<div class="ignored"/>');
|
||||||
|
|
||||||
|
if (branches && branches.length > 1) {
|
||||||
|
var branch_link = $('<a/>')
|
||||||
|
branch_link.text(branch);
|
||||||
|
|
||||||
|
dropdown_menu.append($('<li role="presentation"/>').append(branch_link));
|
||||||
|
branch_link.on('click', function(evt) {
|
||||||
|
current_title = "Regressions in " + branch + " branch";
|
||||||
|
update_url({'branch': [branch]}, false);
|
||||||
|
$("#title").text(current_title);
|
||||||
|
$(".regression-div").hide();
|
||||||
|
$(".ignored").hide();
|
||||||
|
ignored_button.show();
|
||||||
|
$("#regression-div-" + i).show();
|
||||||
|
$("#regression-div-" + i + '-ignored').show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
branch = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
branch_div.attr('id', 'regression-div-' + i);
|
||||||
|
branch_div.hide();
|
||||||
|
main_div.append(branch_div);
|
||||||
|
|
||||||
|
if (params.grouped) {
|
||||||
|
create_grouped_data_table(display_table, ignored_table, ignored_conf_sample_div,
|
||||||
|
data, params, branch, all_ignored_keys);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
create_data_table(display_table, ignored_table, ignored_conf_sample_div,
|
||||||
|
data, params, branch, all_ignored_keys);
|
||||||
|
}
|
||||||
|
branch_div.append(display_table);
|
||||||
|
ignored_table.hide();
|
||||||
|
ignored_conf_sample_div.hide();
|
||||||
|
|
||||||
|
branch_div.append(ignored_table);
|
||||||
|
branch_div.append(ignored_conf_sample_div);
|
||||||
|
|
||||||
|
update_ignore_conf_sample(data, ignored_conf_sample_div, branch);
|
||||||
|
|
||||||
|
branch_div.append(ignored_button);
|
||||||
|
ignored_button.on('click', function(evt) {
|
||||||
|
ignored_button.hide();
|
||||||
|
$(".ignored").show();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var branch_index = 0;
|
||||||
|
if (branches && branches.length > 1) {
|
||||||
|
if (params.branch) {
|
||||||
|
branch_index = branches.indexOf(params.branch[0]);
|
||||||
|
if (branch_index < 0) {
|
||||||
|
branch_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_title = "Regressions in " + branches[branch_index] + " branch";
|
||||||
|
}
|
||||||
|
$("#title").text(current_title);
|
||||||
|
main_div.find("#regression-div-" + branch_index).show();
|
||||||
|
main_div.show();
|
||||||
|
|
||||||
|
if (local_storage_available) {
|
||||||
|
/* Clear out local storage space */
|
||||||
|
var keys = Object.keys(localStorage);
|
||||||
|
$.each(keys, function(i, key) {
|
||||||
|
if (key.slice(0, ignore_key_prefix.length) == ignore_key_prefix &&
|
||||||
|
!all_ignored_keys[key]) {
|
||||||
|
delete localStorage[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return main_div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_data_table(display_table, ignored_table, ignored_conf_sample_div,
|
||||||
|
data, params, branch, all_ignored_keys) {
|
||||||
|
var table_head = $('<thead><tr>' +
|
||||||
|
'<th data-sort="string">Benchmark</th>' +
|
||||||
|
'<th data-sort="string">Date</th>' +
|
||||||
|
'<th data-sort="string">Commit</th>' +
|
||||||
|
'<th data-sort="factor">Factor</th>' +
|
||||||
|
'<th data-sort="value">Before</th>' +
|
||||||
|
'<th data-sort="value">Best after</th>' +
|
||||||
|
'<th></th>' +
|
||||||
|
'</tr></thead>');
|
||||||
|
|
||||||
|
display_table.append(table_head);
|
||||||
|
ignored_table.append(table_head.clone());
|
||||||
|
|
||||||
|
var table_body = $('<tbody/>');
|
||||||
|
var ignored_table_body = $('<tbody/>');
|
||||||
|
|
||||||
|
var regressions = data['regressions'];
|
||||||
|
|
||||||
|
$.each(regressions, function (i, item) {
|
||||||
|
var benchmark_name = item[0];
|
||||||
|
var graph_url = item[1];
|
||||||
|
var param_dict = item[2];
|
||||||
|
var parameter_idx = item[3];
|
||||||
|
var last_value = item[4];
|
||||||
|
var best_value = item[5];
|
||||||
|
var jumps = item[6]; // [[rev1, rev2, before, after], ...]
|
||||||
|
|
||||||
|
if (jumps === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (branch !== null && param_dict['branch'] != branch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var benchmark_basename = benchmark_name.replace(/\([\s\S]*/, '');
|
||||||
|
var benchmark = $.asv.main_json.benchmarks[benchmark_basename];
|
||||||
|
var url_params = {};
|
||||||
|
|
||||||
|
$.each(param_dict, function (key, value) {
|
||||||
|
url_params[key] = [value];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parameter_idx !== null) {
|
||||||
|
$.each($.asv.param_selection_from_flat_idx(benchmark.params, parameter_idx).slice(1), function(i, param_values) {
|
||||||
|
url_params['p-'+benchmark.param_names[i]] = [benchmark.params[i][param_values[0]]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(jumps, function(i, revs) {
|
||||||
|
var row = $('<tr/>');
|
||||||
|
|
||||||
|
var commit_a = $.asv.get_commit_hash(revs[0]);
|
||||||
|
var commit_b = $.asv.get_commit_hash(revs[1]);
|
||||||
|
|
||||||
|
var old_value = revs[2];
|
||||||
|
var new_value = revs[3];
|
||||||
|
|
||||||
|
var factor = new_value / old_value;
|
||||||
|
|
||||||
|
if (commit_a) {
|
||||||
|
url_params.commits = [commit_a + '-' + commit_b];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url_params.commits = [commit_b];
|
||||||
|
}
|
||||||
|
|
||||||
|
var benchmark_url = $.asv.format_hash_string({
|
||||||
|
location: [benchmark_basename],
|
||||||
|
params: url_params
|
||||||
|
});
|
||||||
|
|
||||||
|
new_value = $.asv.pretty_unit(new_value, benchmark.unit);
|
||||||
|
old_value = $.asv.pretty_unit(old_value, benchmark.unit);
|
||||||
|
|
||||||
|
var benchmark_link = $('<a/>').attr('href', benchmark_url).text(benchmark_name);
|
||||||
|
row.append($('<td/>').append(benchmark_link));
|
||||||
|
|
||||||
|
var date_fmt = new Date($.asv.main_json.revision_to_date[revs[1]]);
|
||||||
|
row.append($('<td class="date"/>').text($.asv.format_date_yyyymmdd_hhmm(date_fmt)));
|
||||||
|
|
||||||
|
var commit_td = $('<td/>');
|
||||||
|
|
||||||
|
if (commit_a) {
|
||||||
|
if ($.asv.main_json.show_commit_url.match(/.*\/\/github.com\//)) {
|
||||||
|
var commit_url = ($.asv.main_json.show_commit_url + '../compare/'
|
||||||
|
+ commit_a + '...' + commit_b);
|
||||||
|
commit_td.append(
|
||||||
|
$('<a/>').attr('href', commit_url).text(commit_a + '..' + commit_b));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
commit_td.append($('<span/>').text(commit_a + '..' + commit_b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var commit_url = $.asv.main_json.show_commit_url + commit_b;
|
||||||
|
commit_td.append(
|
||||||
|
$('<a/>').attr('href', commit_url).text(commit_b));
|
||||||
|
}
|
||||||
|
|
||||||
|
row.append(commit_td);
|
||||||
|
|
||||||
|
row.append($('<td/>').text(factor.toFixed(2) + 'x'));
|
||||||
|
row.append($('<td/>').text(old_value));
|
||||||
|
row.append($('<td/>').text(new_value));
|
||||||
|
|
||||||
|
/* html5 local storage has limited size, so store hashes
|
||||||
|
rather than potentially long strings */
|
||||||
|
var ignore_key = get_ignore_key(item, revs);
|
||||||
|
all_ignored_keys[ignore_key] = 1;
|
||||||
|
|
||||||
|
var is_ignored = is_key_ignored(ignore_key);
|
||||||
|
var ignore_button = $('<button class="btn btn-small"/>');
|
||||||
|
|
||||||
|
row.attr('id', ignore_key);
|
||||||
|
|
||||||
|
ignore_button.on('click', function(evt) {
|
||||||
|
if (is_key_ignored(ignore_key)) {
|
||||||
|
set_key_ignore_status(ignore_key, false);
|
||||||
|
var item = ignored_table_body.find('#' + ignore_key).detach();
|
||||||
|
ignore_button.text('Ignore');
|
||||||
|
table_body.append(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_key_ignore_status(ignore_key, true);
|
||||||
|
var item = table_body.find('#' + ignore_key).detach();
|
||||||
|
ignore_button.text('Unignore');
|
||||||
|
ignored_table_body.append(item);
|
||||||
|
}
|
||||||
|
update_ignore_conf_sample(data, ignored_conf_sample_div, branch);
|
||||||
|
});
|
||||||
|
|
||||||
|
row.append($('<td/>').append(ignore_button));
|
||||||
|
|
||||||
|
if (!is_ignored) {
|
||||||
|
ignore_button.text('Ignore');
|
||||||
|
table_body.append(row);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ignore_button.text('Unignore');
|
||||||
|
ignored_table_body.append(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show a graph as a popup */
|
||||||
|
$.asv.ui.hover_graph(benchmark_link, graph_url, benchmark_basename, parameter_idx, [revs]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
display_table.append(table_body);
|
||||||
|
ignored_table.append(ignored_table_body);
|
||||||
|
|
||||||
|
setup_sort(params, display_table);
|
||||||
|
setup_sort(params, ignored_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_grouped_data_table(display_table, ignored_table, ignored_conf_sample_div,
|
||||||
|
data, params, branch, all_ignored_keys) {
|
||||||
|
var table_head = $('<thead><tr>' +
|
||||||
|
'<th data-sort="string">Benchmark</th>' +
|
||||||
|
'<th data-sort="string">Last date</th>' +
|
||||||
|
'<th data-sort="string">Commits</th>' +
|
||||||
|
'<th data-sort="factor">Factor</th>' +
|
||||||
|
'<th data-sort="value">Best</th>' +
|
||||||
|
'<th data-sort="value">Current</th>' +
|
||||||
|
'<th></th>' +
|
||||||
|
'</tr></thead>');
|
||||||
|
|
||||||
|
display_table.append(table_head);
|
||||||
|
ignored_table.append(table_head.clone());
|
||||||
|
|
||||||
|
var table_body = $('<tbody/>');
|
||||||
|
var regressions = data['regressions'];
|
||||||
|
|
||||||
|
$.each(regressions, function (i, item) {
|
||||||
|
var benchmark_name = item[0];
|
||||||
|
var graph_url = item[1];
|
||||||
|
var param_dict = item[2];
|
||||||
|
var parameter_idx = item[3];
|
||||||
|
var last_value = item[4];
|
||||||
|
var best_value = item[5];
|
||||||
|
var jumps = item[6]; // [[rev1, rev2, before, after], ...]
|
||||||
|
|
||||||
|
if (jumps === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (branch !== null && param_dict['branch'] != branch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var benchmark_basename = benchmark_name.replace(/\(.*/, '');
|
||||||
|
var benchmark = $.asv.main_json.benchmarks[benchmark_basename];
|
||||||
|
var url_params = {};
|
||||||
|
|
||||||
|
$.each(param_dict, function (key, value) {
|
||||||
|
url_params[key] = [value];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parameter_idx !== null) {
|
||||||
|
$.each($.asv.param_selection_from_flat_idx(benchmark.params, parameter_idx).slice(1), function(i, param_values) {
|
||||||
|
url_params['p-'+benchmark.param_names[i]] = [benchmark.params[i][param_values[0]]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
url_params.commits = [];
|
||||||
|
|
||||||
|
var commit_td = $('<td/>');
|
||||||
|
|
||||||
|
$.each(jumps, function(i, revs) {
|
||||||
|
var commit_a = $.asv.get_commit_hash(revs[0]);
|
||||||
|
var commit_b = $.asv.get_commit_hash(revs[1]);
|
||||||
|
|
||||||
|
if (commit_a) {
|
||||||
|
url_params.commits = url_params.commits.concat([commit_a + '-' + commit_b]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url_params.commits = url_params.commits.concat([commit_b]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
commit_td.append($('<span>, </span>'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commit_a) {
|
||||||
|
if ($.asv.main_json.show_commit_url.match(/.*\/\/github.com\//)) {
|
||||||
|
var commit_url = ($.asv.main_json.show_commit_url + '../compare/'
|
||||||
|
+ commit_a + '...' + commit_b);
|
||||||
|
commit_td.append(
|
||||||
|
$('<a/>').attr('href', commit_url).text(commit_a + '..' + commit_b));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
commit_td.append($('<span/>').text(commit_a + '..' + commit_b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var commit_url = $.asv.main_json.show_commit_url + commit_b;
|
||||||
|
commit_td.append(
|
||||||
|
$('<a/>').attr('href', commit_url).text(commit_b));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var row = $('<tr/>');
|
||||||
|
|
||||||
|
var benchmark_url = $.asv.format_hash_string({
|
||||||
|
location: [benchmark_basename],
|
||||||
|
params: url_params
|
||||||
|
});
|
||||||
|
|
||||||
|
var benchmark_link = $('<a/>').attr('href', benchmark_url).text(benchmark_name);
|
||||||
|
$.asv.ui.hover_graph(benchmark_link, graph_url, benchmark_basename, parameter_idx, jumps);
|
||||||
|
row.append($('<td/>').append(benchmark_link));
|
||||||
|
|
||||||
|
var date_td = $('<td class="date"/>');
|
||||||
|
var date_fmt = new Date($.asv.main_json.revision_to_date[jumps[jumps.length-1][1]]);
|
||||||
|
date_td.text($.asv.format_date_yyyymmdd_hhmm(date_fmt));
|
||||||
|
row.append(date_td);
|
||||||
|
|
||||||
|
row.append(commit_td);
|
||||||
|
|
||||||
|
var factor_td = $('<td/>');
|
||||||
|
row.append(factor_td);
|
||||||
|
var factor = last_value / best_value;
|
||||||
|
factor_td.text(factor.toFixed(2) + 'x');
|
||||||
|
|
||||||
|
var best_td = $('<td/>');
|
||||||
|
best_td.text($.asv.pretty_unit(best_value, benchmark.unit));
|
||||||
|
row.append(best_td);
|
||||||
|
|
||||||
|
var last_td = $('<td/>');
|
||||||
|
last_td.text($.asv.pretty_unit(last_value, benchmark.unit));
|
||||||
|
row.append(last_td);
|
||||||
|
|
||||||
|
table_body.append(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
display_table.append(table_body);
|
||||||
|
|
||||||
|
setup_sort(params, display_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_ignore_key(item, revs) {
|
||||||
|
var benchmark_name = item[0];
|
||||||
|
var ignore_payload = benchmark_name;
|
||||||
|
|
||||||
|
if (revs[0] === null) {
|
||||||
|
ignore_payload = ignore_payload + ',';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ignore_payload = (ignore_payload + ','
|
||||||
|
+ $.asv.main_json.revision_to_hash[revs[0]]);
|
||||||
|
}
|
||||||
|
ignore_payload = (ignore_payload + ','
|
||||||
|
+ $.asv.main_json.revision_to_hash[revs[1]]);
|
||||||
|
|
||||||
|
return ignore_key_prefix + md5(ignore_payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_key_ignored(ignore_key) {
|
||||||
|
if (local_storage_available) {
|
||||||
|
return (ignore_key in localStorage) || (ignore_key in ignored_regressions);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (ignore_key in ignored_regressions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_key_ignore_status(ignore_key, is_ignored) {
|
||||||
|
if (is_ignored) {
|
||||||
|
if (local_storage_available) {
|
||||||
|
try {
|
||||||
|
localStorage[ignore_key] = 1;
|
||||||
|
} catch (err) {
|
||||||
|
/* Out of quota -- we're just going to ignore that */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignored_regressions[ignore_key] = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (local_storage_available) {
|
||||||
|
delete localStorage[ignore_key];
|
||||||
|
}
|
||||||
|
delete ignored_regressions[ignore_key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_ignore_conf_sample(data, ignored_conf_sample_div, branch) {
|
||||||
|
var regressions = data['regressions'];
|
||||||
|
var entries = {};
|
||||||
|
var branch_suffix = "";
|
||||||
|
|
||||||
|
if (branch) {
|
||||||
|
branch_suffix = "@" + branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(regressions, function (i, item) {
|
||||||
|
var param_dict = item[2];
|
||||||
|
if (branch !== null && param_dict['branch'] != branch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(item[6], function (i, revs) {
|
||||||
|
var ignore_key = get_ignore_key(item, revs);
|
||||||
|
|
||||||
|
if (is_key_ignored(ignore_key)) {
|
||||||
|
var benchmark_name = item[0];
|
||||||
|
var benchmark_name_re = (benchmark_name + branch_suffix).replace(/[.?*+^$[\]\\(){}|-]/g, "\\\\$&");
|
||||||
|
var commit = $.asv.get_commit_hash(revs[1]);
|
||||||
|
var entry = " \"^" + benchmark_name_re + "$\": \"" + commit + "\",\n";
|
||||||
|
entries[entry] = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
entries = Object.keys(entries);
|
||||||
|
entries.sort();
|
||||||
|
|
||||||
|
var text = "// asv.conf.json excerpt for ignoring the above permanently\n\n";
|
||||||
|
text += " \"regressions_first_commits\": {\n";
|
||||||
|
$.each(entries, function (i, entry) {
|
||||||
|
text += entry;
|
||||||
|
});
|
||||||
|
text += " }";
|
||||||
|
|
||||||
|
var pre = $('<pre/>');
|
||||||
|
pre.text(text);
|
||||||
|
ignored_conf_sample_div.empty();
|
||||||
|
ignored_conf_sample_div.append(pre);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_sort(params, table) {
|
||||||
|
table.stupidtable({
|
||||||
|
'value': function(a, b) {
|
||||||
|
function key(s) {
|
||||||
|
for (var k = 0; k < $.asv.time_units.length; ++k) {
|
||||||
|
var entry = $.asv.time_units[k];
|
||||||
|
var m = s.match('^([0-9.]+)'+entry[0]+'$');
|
||||||
|
if (m) {
|
||||||
|
return parseFloat(m[1]) * entry[2] * 1e-30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key(a) - key(b)
|
||||||
|
},
|
||||||
|
'factor': function(a, b) {
|
||||||
|
return parseFloat(a.replace(/x/, '')) - parseFloat(b.replace(/x/, ''));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
table.on('aftertablesort', function (event, data) {
|
||||||
|
update_url({'sort': [data.column], 'dir': [data.direction]}, false);
|
||||||
|
/* Update appearance */
|
||||||
|
table.find('thead th').removeClass('asc');
|
||||||
|
table.find('thead th').removeClass('desc');
|
||||||
|
var th_to_sort = table.find("thead th").eq(parseInt(data.column));
|
||||||
|
if (th_to_sort) {
|
||||||
|
th_to_sort.addClass(data.direction);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (params.sort && params.dir) {
|
||||||
|
var th_to_sort = table.find("thead th").eq(parseInt(params.sort[0]));
|
||||||
|
th_to_sort.stupidsort(params.dir[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var th_to_sort = table.find("thead th").eq(3);
|
||||||
|
th_to_sort.stupidsort("desc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Setup display hooks
|
||||||
|
*/
|
||||||
|
$.asv.register_page('regressions', function(params) {
|
||||||
|
$('#regressions-display').show()
|
||||||
|
load_data(params);
|
||||||
|
});
|
||||||
|
});
|
1
dev/benchmarks/regressions.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"regressions": []}
|
2
dev/benchmarks/regressions.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom"><id>tag:django-components.asv,1970-01-01:/cddbdcca8b398afd301fbfc73cc4d51103d4e3059c0e6b938d4c467ad3d1aa25</id><author><name>Airspeed Velocity</name></author><title xml:lang="en">django-components performance regressions</title><updated>2025-02-22T08:47:12Z</updated></feed>
|
136
dev/benchmarks/summarygrid.js
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
var summary_loaded = false;
|
||||||
|
|
||||||
|
/* Callback a function when an element comes in view */
|
||||||
|
function callback_in_view(element, func) {
|
||||||
|
function handler(evt) {
|
||||||
|
var visible = (
|
||||||
|
$('#summarygrid-display').css('display') != 'none' &&
|
||||||
|
(element.offset().top <= $(window).height() + $(window).scrollTop()) &&
|
||||||
|
(element.offset().top + element.height() >= $(window).scrollTop()));
|
||||||
|
if (visible) {
|
||||||
|
func();
|
||||||
|
$(window).off('scroll', handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(window).on('scroll', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_benchmarks_by_groups() {
|
||||||
|
var main_json = $.asv.main_json;
|
||||||
|
var groups = {};
|
||||||
|
$.each(main_json.benchmarks, function(bm_name, bm) {
|
||||||
|
var i = bm_name.indexOf('.');
|
||||||
|
var group = bm_name.slice(0, i);
|
||||||
|
var name = bm_name.slice(i + 1);
|
||||||
|
if (groups[group] === undefined) {
|
||||||
|
groups[group] = [];
|
||||||
|
}
|
||||||
|
groups[group].push(bm_name);
|
||||||
|
});
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
function benchmark_container(bm) {
|
||||||
|
var container = $(
|
||||||
|
'<a class="btn benchmark-container" href="#' + bm.name +
|
||||||
|
'"/>');
|
||||||
|
var plot_div = $(
|
||||||
|
'<div id="summarygrid-' + bm.name + '" class="benchmark-plot"/>');
|
||||||
|
var display_name = bm.pretty_name || bm.name.slice(bm.name.indexOf('.') + 1);
|
||||||
|
var name = $('<div class="benchmark-text">' + display_name + '</div>');
|
||||||
|
name.tooltip({
|
||||||
|
title: bm.name,
|
||||||
|
html: true,
|
||||||
|
placement: 'top',
|
||||||
|
container: 'body',
|
||||||
|
animation: false
|
||||||
|
});
|
||||||
|
|
||||||
|
plot_div.tooltip({
|
||||||
|
title: bm.code,
|
||||||
|
html: true,
|
||||||
|
placement: 'bottom',
|
||||||
|
container: 'body',
|
||||||
|
animation: false
|
||||||
|
});
|
||||||
|
|
||||||
|
container.append(name);
|
||||||
|
container.append(plot_div);
|
||||||
|
|
||||||
|
callback_in_view(plot_div, function() {
|
||||||
|
$.asv.load_graph_data(
|
||||||
|
'graphs/summary/' + bm.name + '.json'
|
||||||
|
).done(function(data) {
|
||||||
|
var options = {
|
||||||
|
colors: $.asv.colors,
|
||||||
|
series: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
lineWidth: 2
|
||||||
|
},
|
||||||
|
shadowSize: 0
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
borderWidth: 1,
|
||||||
|
margin: 0,
|
||||||
|
labelMargin: 0,
|
||||||
|
axisMargin: 0,
|
||||||
|
minBorderMargin: 0
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
ticks: [],
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
ticks: [],
|
||||||
|
min: 0
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var plot = $.plot(
|
||||||
|
plot_div, [{data: data}], options);
|
||||||
|
}).fail(function() {
|
||||||
|
// TODO: Handle failure
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_summary() {
|
||||||
|
var summary_display = $('#summarygrid-display');
|
||||||
|
var main_json = $.asv.main_json;
|
||||||
|
var summary_container = $('<div/>');
|
||||||
|
|
||||||
|
if (summary_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(get_benchmarks_by_groups(), function(group, benchmarks) {
|
||||||
|
var group_container = $('<div class="benchmark-group"/>')
|
||||||
|
group_container.attr('id', 'group-' + group)
|
||||||
|
group_container.append($('<h1>' + group + '</h1>'));
|
||||||
|
summary_display.append(group_container);
|
||||||
|
$.each(benchmarks, function(i, bm_name) {
|
||||||
|
var bm = $.asv.main_json.benchmarks[bm_name];
|
||||||
|
group_container.append(benchmark_container(bm));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
summary_display.append(summary_container);
|
||||||
|
$(window).trigger('scroll');
|
||||||
|
|
||||||
|
summary_loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.asv.register_page('', function(params) {
|
||||||
|
$('#summarygrid-display').show();
|
||||||
|
$("#title").text("All benchmarks");
|
||||||
|
$('.tooltip').remove();
|
||||||
|
make_summary();
|
||||||
|
});
|
||||||
|
});
|
50
dev/benchmarks/summarylist.css
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#summarylist-body {
|
||||||
|
padding-left: 2em;
|
||||||
|
padding-right: 2em;
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table thead th {
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table thead th.desc:after {
|
||||||
|
content: ' \2191';
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table thead th.asc:after {
|
||||||
|
content: ' \2193';
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table.ignored {
|
||||||
|
padding-top: 1em;
|
||||||
|
color: #ccc;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table.ignored a {
|
||||||
|
color: #82abda;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table tbody td.positive-change {
|
||||||
|
background-color: #fdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table tbody td.negative-change {
|
||||||
|
background-color: #dfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table tbody td.value {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table tbody td.change a {
|
||||||
|
color: black;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarylist-body table tbody td.change-date {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
451
dev/benchmarks/summarylist.js
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
/* The state of the parameters in the sidebar. Dictionary mapping
|
||||||
|
strings to values determining the "enabled" configurations. */
|
||||||
|
var state = null;
|
||||||
|
/* Cache of constructed tables, {data_path: table_dom_id} */
|
||||||
|
var table_cache = {};
|
||||||
|
var table_cache_counter = 0;
|
||||||
|
|
||||||
|
function setup_display(state_selection) {
|
||||||
|
var new_state = setup_state(state_selection);
|
||||||
|
var same_state = (state !== null);
|
||||||
|
|
||||||
|
/* Avoid needless UI updates, e.g., on table sort */
|
||||||
|
|
||||||
|
if (same_state) {
|
||||||
|
$.each(state, function (key, value) {
|
||||||
|
if (value != new_state[key]) {
|
||||||
|
same_state = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!same_state) {
|
||||||
|
state = new_state;
|
||||||
|
replace_params_ui();
|
||||||
|
|
||||||
|
var filename = $.asv.graph_to_path('summary', state);
|
||||||
|
|
||||||
|
$("#summarylist-body table").hide();
|
||||||
|
$("#summarylist-body .message").remove();
|
||||||
|
|
||||||
|
if (table_cache[filename] !== undefined) {
|
||||||
|
$(table_cache[filename]).show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#summarylist-body").append($("<p class='message'>Loading...</p>"));
|
||||||
|
$.asv.load_graph_data(
|
||||||
|
filename
|
||||||
|
).done(function (data) {
|
||||||
|
var table = construct_benchmark_table(data);
|
||||||
|
var table_name = 'summarylist-table-' + table_cache_counter;
|
||||||
|
++table_cache_counter;
|
||||||
|
|
||||||
|
table.attr('id', table_name);
|
||||||
|
table_cache[filename] = '#' + table_name;
|
||||||
|
$("#summarylist-body .message").remove();
|
||||||
|
$("#summarylist-body").append(table);
|
||||||
|
table.show()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_state_url(key, value) {
|
||||||
|
var info = $.asv.parse_hash_string(window.location.hash);
|
||||||
|
var new_state = get_valid_state(state, key, value);
|
||||||
|
|
||||||
|
$.each($.asv.main_json.params, function(param, values) {
|
||||||
|
if (values.length > 1) {
|
||||||
|
info.params[param] = [new_state[param]];
|
||||||
|
}
|
||||||
|
else if (info.params[param]) {
|
||||||
|
delete info.params[param];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.location.hash = $.asv.format_hash_string(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function obj_copy(obj) {
|
||||||
|
var newobj = {};
|
||||||
|
$.each(obj, function(key, val) {
|
||||||
|
newobj[key] = val;
|
||||||
|
});
|
||||||
|
return newobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function obj_diff(obj1, obj2) {
|
||||||
|
var count = 0;
|
||||||
|
$.each(obj1, function(key, val) {
|
||||||
|
if (obj2[key] != val) {
|
||||||
|
++count
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_valid_state(tmp_state, wanted_key, wanted_value) {
|
||||||
|
/*
|
||||||
|
Get an available state with wanted_key having wanted_value,
|
||||||
|
preferably as a minor modification of tmp_state.
|
||||||
|
*/
|
||||||
|
var best_params = null;
|
||||||
|
var best_diff = 1e99;
|
||||||
|
var best_hit = false;
|
||||||
|
|
||||||
|
tmp_state = obj_copy(tmp_state);
|
||||||
|
if (wanted_key !== undefined) {
|
||||||
|
tmp_state[wanted_key] = wanted_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each($.asv.main_json.graph_param_list, function(idx, params) {
|
||||||
|
var diff = obj_diff(tmp_state, params);
|
||||||
|
var hit = (wanted_key === undefined || params[wanted_key] == wanted_value);
|
||||||
|
|
||||||
|
if ((!best_hit && hit) || (hit == best_hit && diff < best_diff)) {
|
||||||
|
best_params = params;
|
||||||
|
best_diff = diff;
|
||||||
|
best_hit = hit;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (best_params === null) {
|
||||||
|
best_params = $.asv.main_json.graph_param_list[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj_copy(best_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_state(state_selection) {
|
||||||
|
var index = $.asv.main_json;
|
||||||
|
var state = {};
|
||||||
|
|
||||||
|
state.machine = index.params.machine;
|
||||||
|
|
||||||
|
$.each(index.params, function(param, values) {
|
||||||
|
state[param] = values[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state_selection !== null) {
|
||||||
|
/* Select a specific generic parameter state */
|
||||||
|
$.each(index.params, function(param, values) {
|
||||||
|
if (state_selection[param]) {
|
||||||
|
state[param] = state_selection[param][0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_valid_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function replace_params_ui() {
|
||||||
|
var index = $.asv.main_json;
|
||||||
|
|
||||||
|
var nav = $('#summarylist-navigation');
|
||||||
|
nav.empty();
|
||||||
|
|
||||||
|
/* Machine selection */
|
||||||
|
$.asv.ui.make_value_selector_panel(nav, 'machine', index.params.machine, function(i, machine, button) {
|
||||||
|
button.text(machine);
|
||||||
|
|
||||||
|
button.on('click', function(evt) {
|
||||||
|
update_state_url('machine', machine);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (state.machine != machine) {
|
||||||
|
button.removeClass('active');
|
||||||
|
}
|
||||||
|
button.removeAttr('data-toggle');
|
||||||
|
|
||||||
|
/* Create tooltips for each machine */
|
||||||
|
var details = [];
|
||||||
|
$.each(index.machines[machine], function(key, val) {
|
||||||
|
details.push(key + ': ' + val);
|
||||||
|
});
|
||||||
|
details = details.join('<br/>');
|
||||||
|
|
||||||
|
button.tooltip({
|
||||||
|
title: details,
|
||||||
|
html: true,
|
||||||
|
placement: 'right',
|
||||||
|
container: 'body',
|
||||||
|
animation: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Generic parameter selectors */
|
||||||
|
$.each(index.params, function(param, values) {
|
||||||
|
if (values.length > 1 && param != 'machine') {
|
||||||
|
$.asv.ui.make_value_selector_panel(nav, param, values, function(i, value, button) {
|
||||||
|
var value_display;
|
||||||
|
if (value === null)
|
||||||
|
value_display = '[none]';
|
||||||
|
else if (!value)
|
||||||
|
value_display = '[default]';
|
||||||
|
else
|
||||||
|
value_display = value;
|
||||||
|
|
||||||
|
button.text(value_display);
|
||||||
|
|
||||||
|
if (state[param] != value) {
|
||||||
|
button.removeClass('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
button.on('click', function(evt) {
|
||||||
|
update_state_url(param, value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(nav).find(".btn-group").removeAttr("data-toggle");
|
||||||
|
|
||||||
|
$.asv.ui.reflow_value_selector_panels();
|
||||||
|
}
|
||||||
|
|
||||||
|
function construct_benchmark_table(data) {
|
||||||
|
var index = $.asv.main_json;
|
||||||
|
|
||||||
|
/* Form a new table */
|
||||||
|
|
||||||
|
var table = $('<table class="table table-hover"/>');
|
||||||
|
|
||||||
|
var table_head = $('<thead><tr>' +
|
||||||
|
'<th data-sort="string">Benchmark</th>' +
|
||||||
|
'<th data-sort="float">Value</th>' +
|
||||||
|
'<th data-sort="float">Recent change</th>' +
|
||||||
|
'<th data-sort="string">Changed at</th>' +
|
||||||
|
'</tr></thead>');
|
||||||
|
table.append(table_head);
|
||||||
|
|
||||||
|
var table_body = $('<tbody/>');
|
||||||
|
|
||||||
|
$.each(data, function(row_idx, row) {
|
||||||
|
var tr = $('<tr/>');
|
||||||
|
var name_td = $('<td/>');
|
||||||
|
var name = $('<a/>');
|
||||||
|
var benchmark_url_args = {};
|
||||||
|
var benchmark_full_url;
|
||||||
|
var benchmark_base_url;
|
||||||
|
|
||||||
|
/* Format benchmark url */
|
||||||
|
benchmark_url_args.location = [row.name];
|
||||||
|
benchmark_url_args.params = {};
|
||||||
|
$.each($.asv.main_json.params, function (key, values) {
|
||||||
|
if (values.length > 1) {
|
||||||
|
benchmark_url_args.params[key] = [state[key]];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
benchmark_base_url = $.asv.format_hash_string(benchmark_url_args);
|
||||||
|
if (row.idx !== null) {
|
||||||
|
var benchmark = $.asv.main_json.benchmarks[row.name];
|
||||||
|
$.each($.asv.param_selection_from_flat_idx(benchmark.params, row.idx).slice(1),
|
||||||
|
function(i, param_values) {
|
||||||
|
benchmark_url_args.params['p-'+benchmark.param_names[i]]
|
||||||
|
= [benchmark.params[i][param_values[0]]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
benchmark_full_url = $.asv.format_hash_string(benchmark_url_args);
|
||||||
|
|
||||||
|
/* Benchmark name column */
|
||||||
|
var bm_link;
|
||||||
|
if (row.idx === null) {
|
||||||
|
bm_link = $('<a/>').attr('href', benchmark_base_url).text(row.pretty_name);
|
||||||
|
name_td.append(bm_link);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var basename = row.pretty_name;
|
||||||
|
var args = null;
|
||||||
|
var m = row.pretty_name.match(/(.*)\(.*$/);
|
||||||
|
if (m) {
|
||||||
|
basename = m[1];
|
||||||
|
args = row.pretty_name.slice(basename.length);
|
||||||
|
}
|
||||||
|
bm_link = $('<a/>').attr('href', benchmark_base_url).text(basename);
|
||||||
|
name_td.append(bm_link);
|
||||||
|
if (args) {
|
||||||
|
var bm_idx_link;
|
||||||
|
var graph_url;
|
||||||
|
bm_idx_link = $('<a/>').attr('href', benchmark_full_url).text(' ' + args);
|
||||||
|
name_td.append(bm_idx_link);
|
||||||
|
graph_url = $.asv.graph_to_path(row.name, state);
|
||||||
|
$.asv.ui.hover_graph(bm_idx_link, graph_url, row.name, row.idx, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.asv.ui.hover_summary_graph(bm_link, row.name);
|
||||||
|
|
||||||
|
/* Value column */
|
||||||
|
var value_td = $('<td class="value"/>');
|
||||||
|
if (row.last_value !== null) {
|
||||||
|
var value, err, err_str, sort_value;
|
||||||
|
var unit = $.asv.main_json.benchmarks[row.name].unit;
|
||||||
|
value = $.asv.pretty_unit(row.last_value, unit);
|
||||||
|
if (unit == "seconds") {
|
||||||
|
sort_value = row.last_value * 1e100;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sort_value = row.last_value;
|
||||||
|
}
|
||||||
|
var value_span = $('<span/>').text(value);
|
||||||
|
|
||||||
|
err = 100*row.last_err/row.last_value;
|
||||||
|
if (err == err) {
|
||||||
|
err_str = " \u00b1 " + err.toFixed(0.1) + '%';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err_str = "";
|
||||||
|
}
|
||||||
|
value_span.attr('data-toggle', 'tooltip');
|
||||||
|
value_span.attr('title', value + err_str);
|
||||||
|
value_td.append(value_span);
|
||||||
|
value_td.attr('data-sort-value', sort_value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value_td.attr('data-sort-value', -1e99);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change percentage column */
|
||||||
|
var change_td = $('<td class="change"/>');
|
||||||
|
if (row.prev_value !== null) {
|
||||||
|
var text, change_str, change = 0, sort_value = 0;
|
||||||
|
var unit = $.asv.main_json.benchmarks[row.name].unit;
|
||||||
|
change_str = $.asv.pretty_unit(row.last_value - row.prev_value, unit);
|
||||||
|
if (!change_str.match(/^-/)) {
|
||||||
|
change_str = '+' + change_str;
|
||||||
|
}
|
||||||
|
if (row.prev_value != 0) {
|
||||||
|
change = 100 * (row.last_value / row.prev_value - 1);
|
||||||
|
text = change.toFixed(1) + '% (' + change_str + ')';
|
||||||
|
if (change > 0) {
|
||||||
|
text = '+' + text;
|
||||||
|
}
|
||||||
|
sort_value = change;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text = ' (' + change_str + ')';
|
||||||
|
}
|
||||||
|
text = text.replace('-', '\u2212');
|
||||||
|
|
||||||
|
var change_commit_a = $.asv.main_json.revision_to_hash[row.change_rev[0]];
|
||||||
|
var change_commit_b = $.asv.main_json.revision_to_hash[row.change_rev[1]];
|
||||||
|
var change_q;
|
||||||
|
if (change_commit_a === undefined) {
|
||||||
|
change_q = '&commits=' + change_commit_b;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
change_q = '&commits=' + change_commit_a + '-' + change_commit_b;
|
||||||
|
}
|
||||||
|
var change_link = $('<a/>').attr('href', benchmark_full_url + change_q).text(text);
|
||||||
|
|
||||||
|
graph_url = $.asv.graph_to_path(row.name, state);
|
||||||
|
$.asv.ui.hover_graph(change_link, graph_url, row.name, row.idx, [row.change_rev]);
|
||||||
|
|
||||||
|
change_td.append(change_link);
|
||||||
|
|
||||||
|
if (change > 5) {
|
||||||
|
change_td.addClass('positive-change');
|
||||||
|
}
|
||||||
|
else if (change < -5) {
|
||||||
|
change_td.addClass('negative-change');
|
||||||
|
}
|
||||||
|
change_td.attr('data-sort-value', sort_value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
change_td.attr('data-sort-value', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change date column */
|
||||||
|
var changed_at_td = $('<td class="change-date"/>');
|
||||||
|
if (row.change_rev !== null) {
|
||||||
|
var date = new Date($.asv.main_json.revision_to_date[row.change_rev[1]]);
|
||||||
|
var commit_1 = $.asv.get_commit_hash(row.change_rev[0]);
|
||||||
|
var commit_2 = $.asv.get_commit_hash(row.change_rev[1]);
|
||||||
|
var commit_a = $('<a/>');
|
||||||
|
var span = $('<span/>');
|
||||||
|
if (commit_1) {
|
||||||
|
var commit_url;
|
||||||
|
if ($.asv.main_json.show_commit_url.match(/.*\/\/github.com\//)) {
|
||||||
|
commit_url = ($.asv.main_json.show_commit_url + '../compare/'
|
||||||
|
+ commit_1 + '...' + commit_2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
commit_url = $.asv.main_json.show_commit_url + commit_2;
|
||||||
|
}
|
||||||
|
commit_a.attr('href', commit_url);
|
||||||
|
commit_a.text(commit_1 + '...' + commit_2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
commit_a.attr('href', $.asv.main_json.show_commit_url + commit_2);
|
||||||
|
commit_a.text(commit_2);
|
||||||
|
}
|
||||||
|
span.text($.asv.format_date_yyyymmdd(date) + ' ');
|
||||||
|
span.append(commit_a);
|
||||||
|
changed_at_td.append(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.append(name_td);
|
||||||
|
tr.append(value_td);
|
||||||
|
tr.append(change_td);
|
||||||
|
tr.append(changed_at_td);
|
||||||
|
|
||||||
|
table_body.append(tr);
|
||||||
|
});
|
||||||
|
|
||||||
|
table_body.find('[data-toggle="tooltip"]').tooltip();
|
||||||
|
|
||||||
|
/* Finalize */
|
||||||
|
table.append(table_body);
|
||||||
|
setup_sort(table);
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_sort(table) {
|
||||||
|
var info = $.asv.parse_hash_string(window.location.hash);
|
||||||
|
|
||||||
|
table.stupidtable();
|
||||||
|
|
||||||
|
table.on('aftertablesort', function (event, data) {
|
||||||
|
var info = $.asv.parse_hash_string(window.location.hash);
|
||||||
|
info.params['sort'] = [data.column];
|
||||||
|
info.params['dir'] = [data.direction];
|
||||||
|
window.location.hash = $.asv.format_hash_string(info);
|
||||||
|
|
||||||
|
/* Update appearance */
|
||||||
|
table.find('thead th').removeClass('asc');
|
||||||
|
table.find('thead th').removeClass('desc');
|
||||||
|
var th_to_sort = table.find("thead th").eq(parseInt(data.column));
|
||||||
|
if (th_to_sort) {
|
||||||
|
th_to_sort.addClass(data.direction);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (info.params.sort && info.params.dir) {
|
||||||
|
var th_to_sort = table.find("thead th").eq(parseInt(info.params.sort[0]));
|
||||||
|
th_to_sort.stupidsort(info.params.dir[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var th_to_sort = table.find("thead th").eq(0);
|
||||||
|
th_to_sort.stupidsort("asc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entry point
|
||||||
|
*/
|
||||||
|
$.asv.register_page('summarylist', function(params) {
|
||||||
|
var state_selection = null;
|
||||||
|
|
||||||
|
if (Object.keys(params).length > 0) {
|
||||||
|
state_selection = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_display(state_selection);
|
||||||
|
|
||||||
|
$('#summarylist-display').show();
|
||||||
|
$("#title").text("List of benchmarks");
|
||||||
|
});
|
||||||
|
});
|
BIN
dev/benchmarks/swallow.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
dev/benchmarks/swallow.png
Normal file
After Width: | Height: | Size: 893 B |