summaryrefslogtreecommitdiff
path: root/website/app.ts
diff options
context:
space:
mode:
Diffstat (limited to 'website/app.ts')
-rw-r--r--website/app.ts480
1 files changed, 0 insertions, 480 deletions
diff --git a/website/app.ts b/website/app.ts
deleted file mode 100644
index 809be51bb..000000000
--- a/website/app.ts
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-
-// How much to multiply time values in order to process log graphs properly.
-const TimeScaleFactor = 10000;
-
-export interface BenchmarkExecTimeResult {
- min?: number;
- max?: number;
- mean?: number;
- stddev?: number;
- system?: number;
- user?: number;
-}
-
-export interface BenchmarkExecTimeResultSet {
- [variant: string]: BenchmarkExecTimeResult;
-}
-
-export interface BenchmarkVariantsResultSet {
- [variant: string]: number;
-}
-
-export interface BenchmarkRun {
- created_at: string;
- sha1: string;
- benchmark: BenchmarkExecTimeResultSet;
- binary_size?: BenchmarkVariantsResultSet | number;
- max_memory?: BenchmarkVariantsResultSet | number;
- bundle_size?: BenchmarkVariantsResultSet;
- max_latency?: BenchmarkVariantsResultSet;
- req_per_sec?: BenchmarkVariantsResultSet;
- req_per_sec_proxy?: BenchmarkVariantsResultSet;
- syscall_count?: BenchmarkVariantsResultSet;
- thread_count?: BenchmarkVariantsResultSet;
- throughput?: BenchmarkVariantsResultSet;
-}
-
-export type BenchmarkName = Exclude<keyof BenchmarkRun, "created_at" | "sha1">;
-
-type Column = [string, ...Array<number | null>];
-
-interface C3DataNode {
- id: string;
- index: number;
- name: string;
- value: number;
- x: number;
-}
-
-type C3OnClickCallback = (C3DataNode, unknown) => void;
-type C3OnRenderedCallback = () => void;
-type C3TickFormatter = (number) => number | string;
-
-export async function getJson(path: string): Promise<unknown> {
- return (await fetch(path)).json();
-}
-
-function getBenchmarkVarieties(
- data: BenchmarkRun[],
- benchmarkName: BenchmarkName
-): string[] {
- // Look at last sha hash.
- const last = data[data.length - 1];
- return Object.keys(last[benchmarkName]);
-}
-
-export function createColumns(
- data: BenchmarkRun[],
- benchmarkName: BenchmarkName
-): Column[] {
- const varieties = getBenchmarkVarieties(data, benchmarkName);
- return varieties.map(variety => [
- variety,
- ...data.map(d => {
- if (d[benchmarkName] != null) {
- if (d[benchmarkName][variety] != null) {
- const v = d[benchmarkName][variety];
- if (benchmarkName == "benchmark") {
- const meanValue = v ? v.mean : 0;
- return meanValue || null;
- } else {
- return v;
- }
- }
- }
- return null;
- })
- ]);
-}
-
-export function createNormalizedColumns(
- data: BenchmarkRun[],
- benchmarkName: BenchmarkName,
- baselineBenchmark: BenchmarkName,
- baselineVariety: string
-): Column[] {
- const varieties = getBenchmarkVarieties(data, benchmarkName);
- return varieties.map(variety => [
- variety,
- ...data.map(d => {
- if (d[baselineBenchmark] != null) {
- if (d[baselineBenchmark][baselineVariety] != null) {
- const baseline = d[baselineBenchmark][baselineVariety];
- if (d[benchmarkName] != null) {
- if (d[benchmarkName][variety] != null && baseline != 0) {
- const v = d[benchmarkName][variety];
- if (benchmarkName == "benchmark") {
- const meanValue = v ? v.mean : 0;
- return meanValue || null;
- } else {
- return v / baseline;
- }
- }
- }
- }
- }
- return null;
- })
- ]);
-}
-
-export function createExecTimeColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "benchmark");
-}
-
-export function createThroughputColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "throughput");
-}
-
-export function createProxyColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "req_per_sec_proxy");
-}
-
-export function createNormalizedProxyColumns(data: BenchmarkRun[]): Column[] {
- return createNormalizedColumns(
- data,
- "req_per_sec_proxy",
- "req_per_sec",
- "hyper"
- );
-}
-
-export function createReqPerSecColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "req_per_sec");
-}
-
-export function createNormalizedReqPerSecColumns(
- data: BenchmarkRun[]
-): Column[] {
- return createNormalizedColumns(data, "req_per_sec", "req_per_sec", "hyper");
-}
-
-export function createMaxLatencyColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "max_latency");
-}
-
-export function createMaxMemoryColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "max_memory");
-}
-
-export function createBinarySizeColumns(data: BenchmarkRun[]): Column[] {
- const propName = "binary_size";
- const binarySizeNames = Object.keys(data[data.length - 1][propName]);
- return binarySizeNames.map(name => [
- name,
- ...data.map(d => {
- const binarySizeData = d["binary_size"];
- switch (typeof binarySizeData) {
- case "number": // legacy implementation
- return name === "deno" ? binarySizeData : 0;
- default:
- if (!binarySizeData) {
- return null;
- }
- return binarySizeData[name] || null;
- }
- })
- ]);
-}
-
-export function createThreadCountColumns(data: BenchmarkRun[]): Column[] {
- const propName = "thread_count";
- const threadCountNames = Object.keys(data[data.length - 1][propName]);
- return threadCountNames.map(name => [
- name,
- ...data.map(d => {
- const threadCountData = d[propName];
- if (!threadCountData) {
- return null;
- }
- return threadCountData[name] || null;
- })
- ]);
-}
-
-export function createSyscallCountColumns(data: BenchmarkRun[]): Column[] {
- const propName = "syscall_count";
- const syscallCountNames = Object.keys(data[data.length - 1][propName]);
- return syscallCountNames.map(name => [
- name,
- ...data.map(d => {
- const syscallCountData = d[propName];
- if (!syscallCountData) {
- return null;
- }
- return syscallCountData[name] || null;
- })
- ]);
-}
-
-export function createBundleSizeColumns(data: BenchmarkRun[]): Column[] {
- return createColumns(data, "bundle_size");
-}
-
-export function createSha1List(data: BenchmarkRun[]): string[] {
- return data.map(d => d.sha1);
-}
-
-export function formatKB(bytes: number): string {
- return (bytes / 1024).toFixed(2);
-}
-
-export function formatMB(bytes: number): string {
- return (bytes / (1024 * 1024)).toFixed(2);
-}
-
-export function formatReqSec(reqPerSec: number): string {
- return (reqPerSec / 1000).toFixed(3);
-}
-
-export function formatPercentage(decimal: number): string {
- return (decimal * 100).toFixed(2);
-}
-
-/**
- * @param {string} id The id of dom element
- * @param {string[]} categories categories for x-axis values
- * @param {any[][]} columns The columns data
- * @param {function} onclick action on clicking nodes of chart
- * @param {string} yLabel label of y axis
- * @param {function} yTickFormat formatter of y axis ticks
- * @param {boolean} zoomEnabled enables the zoom feature
- */
-function generate(
- id: string,
- categories: string[],
- columns: Column[],
- onclick: C3OnClickCallback,
- yLabel = "",
- yTickFormat?: C3TickFormatter,
- zoomEnabled = true,
- onrendered?: C3OnRenderedCallback
-): void {
- const yAxis = {
- padding: { bottom: 0 },
- min: 0,
- label: yLabel,
- tick: null
- };
- if (yTickFormat) {
- yAxis.tick = {
- format: yTickFormat
- };
- if (yTickFormat == logScale) {
- delete yAxis.min;
- for (const col of columns) {
- for (let i = 1; i < col.length; i++) {
- if (col[i] == null || col[i] === 0) {
- continue;
- }
- col[i] = Math.log10((col[i] as number) * TimeScaleFactor);
- }
- }
- }
- }
-
- // @ts-ignore
- c3.generate({
- bindto: id,
- onrendered,
- data: {
- columns,
- onclick
- },
- axis: {
- x: {
- type: "category",
- show: false,
- categories
- },
- y: yAxis
- },
- zoom: {
- enabled: zoomEnabled
- }
- });
-}
-
-function logScale(t: number): string {
- return (Math.pow(10, t) / TimeScaleFactor).toFixed(4);
-}
-
-/**
- * @param dataUrl The url of benchmark data json.
- */
-export function drawCharts(dataUrl: string): Promise<void> {
- // TODO Using window["location"]["hostname"] instead of
- // window.location.hostname because when deno runs app_test.js it gets a type
- // error here, not knowing about window.location. Ideally Deno would skip
- // type check entirely on JS files.
- if (window["location"]["hostname"] != "deno.github.io") {
- dataUrl = "https://denoland.github.io/deno/" + dataUrl;
- }
- return drawChartsFromBenchmarkData(dataUrl);
-}
-
-const proxyFields: BenchmarkName[] = ["req_per_sec"];
-function extractProxyFields(data: BenchmarkRun[]): void {
- for (const row of data) {
- for (const field of proxyFields) {
- const d = row[field];
- if (!d) continue;
- const name = field + "_proxy";
- const newField = {};
- row[name] = newField;
- for (const k of Object.getOwnPropertyNames(d)) {
- if (k.includes("_proxy")) {
- const v = d[k];
- delete d[k];
- newField[k] = v;
- }
- }
- }
- }
-}
-/**
- * Draws the charts from the benchmark data stored in gh-pages branch.
- */
-export async function drawChartsFromBenchmarkData(
- dataUrl: string
-): Promise<void> {
- const data = (await getJson(dataUrl)) as BenchmarkRun[];
-
- // hack to extract proxy fields from req/s fields
- extractProxyFields(data);
-
- const execTimeColumns = createExecTimeColumns(data);
- const throughputColumns = createThroughputColumns(data);
- const reqPerSecColumns = createReqPerSecColumns(data);
- const normalizedReqPerSecColumns = createNormalizedReqPerSecColumns(data);
- const proxyColumns = createProxyColumns(data);
- const normalizedProxyColumns = createNormalizedProxyColumns(data);
- const maxLatencyColumns = createMaxLatencyColumns(data);
- const maxMemoryColumns = createMaxMemoryColumns(data);
- const binarySizeColumns = createBinarySizeColumns(data);
- const threadCountColumns = createThreadCountColumns(data);
- const syscallCountColumns = createSyscallCountColumns(data);
- const bundleSizeColumns = createBundleSizeColumns(data);
- const sha1List = createSha1List(data);
- const sha1ShortList = sha1List.map(sha1 => sha1.substring(0, 6));
-
- function viewCommitOnClick(d: C3DataNode, _: unknown): void {
- // @ts-ignore
- window.open(`https://github.com/denoland/deno/commit/${sha1List[d.index]}`);
- }
-
- function gen(
- id: string,
- columns: Column[],
- yLabel = "",
- yTickFormat?: C3TickFormatter,
- onrendered?: C3OnRenderedCallback
- ): void {
- generate(
- id,
- sha1ShortList,
- columns,
- viewCommitOnClick,
- yLabel,
- yTickFormat,
- true,
- onrendered
- );
- }
-
- gen("#exec-time-chart", execTimeColumns, "seconds", logScale);
- gen("#throughput-chart", throughputColumns, "seconds", logScale);
- gen("#req-per-sec-chart", reqPerSecColumns, "1000 req/sec", formatReqSec);
- gen(
- "#normalized-req-per-sec-chart",
- normalizedReqPerSecColumns,
- "% of hyper througput",
- formatPercentage,
- hideOnRender("normalized-req-per-sec-chart")
- );
- gen("#proxy-req-per-sec-chart", proxyColumns, "req/sec");
- gen(
- "#normalized-proxy-req-per-sec-chart",
- normalizedProxyColumns,
- "% of hyper througput",
- formatPercentage,
- hideOnRender("normalized-proxy-req-per-sec-chart")
- );
- gen("#max-latency-chart", maxLatencyColumns, "milliseconds", logScale);
- gen("#max-memory-chart", maxMemoryColumns, "megabytes", formatMB);
- gen("#binary-size-chart", binarySizeColumns, "megabytes", formatMB);
- gen("#thread-count-chart", threadCountColumns, "threads");
- gen("#syscall-count-chart", syscallCountColumns, "syscalls");
- gen("#bundle-size-chart", bundleSizeColumns, "kilobytes", formatKB);
-}
-
-function hideOnRender(elementID: string): C3OnRenderedCallback {
- return (): void => {
- const chart = window["document"].getElementById(elementID);
- if (!chart.getAttribute("data-inital-hide-done")) {
- chart.setAttribute("data-inital-hide-done", "true");
- chart.classList.add("hidden");
- }
- };
-}
-
-function registerNormalizedSwitcher(
- checkboxID: string,
- chartID: string,
- normalizedChartID: string
-): void {
- const checkbox = window["document"].getElementById(checkboxID);
- const regularChart = window["document"].getElementById(chartID);
- const normalizedChart = window["document"].getElementById(normalizedChartID);
-
- checkbox.addEventListener("change", _ => {
- // If checked is true the normalized variant should be shown
- // @ts-ignore
- if (checkbox.checked) {
- regularChart.classList.add("hidden");
- normalizedChart.classList.remove("hidden");
- } else {
- normalizedChart.classList.add("hidden");
- regularChart.classList.remove("hidden");
- }
- });
-}
-
-export function main(): void {
- window["chartWidth"] = 800;
- const overlay = window["document"].getElementById("spinner-overlay");
-
- function showSpinner(): void {
- overlay.style.display = "block";
- }
-
- function hideSpinner(): void {
- overlay.style.display = "none";
- }
-
- function updateCharts(): void {
- const u = window.location.hash.match("all") ? "./data.json" : "recent.json";
-
- showSpinner();
-
- drawCharts(u)
- .then(hideSpinner)
- .catch(hideSpinner);
- }
- updateCharts();
-
- registerNormalizedSwitcher(
- "req-per-sec-chart-show-normalized",
- "req-per-sec-chart",
- "normalized-req-per-sec-chart"
- );
-
- registerNormalizedSwitcher(
- "proxy-req-per-sec-chart-show-normalized",
- "proxy-req-per-sec-chart",
- "normalized-proxy-req-per-sec-chart"
- );
-
- window["onhashchange"] = updateCharts;
-}