From 6e84ea40616ab95d90f7ff6f8ab1f7723dea7112 Mon Sep 17 00:00:00 2001 From: Corentin Thomasset Date: Wed, 5 Apr 2023 22:55:40 +0200 Subject: [PATCH] feat(new-tool): simple benchmark calculator --- .../benchmark-builder.models.ts | 34 +++++ .../benchmark-builder/benchmark-builder.vue | 117 ++++++++++++++++++ .../benchmark-builder/dynamic-values.vue | 61 +++++++++ src/tools/benchmark-builder/index.ts | 11 ++ src/tools/index.ts | 3 +- 5 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 src/tools/benchmark-builder/benchmark-builder.models.ts create mode 100644 src/tools/benchmark-builder/benchmark-builder.vue create mode 100644 src/tools/benchmark-builder/dynamic-values.vue create mode 100644 src/tools/benchmark-builder/index.ts diff --git a/src/tools/benchmark-builder/benchmark-builder.models.ts b/src/tools/benchmark-builder/benchmark-builder.models.ts new file mode 100644 index 00000000..be8f9658 --- /dev/null +++ b/src/tools/benchmark-builder/benchmark-builder.models.ts @@ -0,0 +1,34 @@ +import _ from 'lodash'; + +export { computeAverage, computeVariance, arrayToMarkdownTable }; + +function computeAverage({ data }: { data: number[] }) { + if (data.length === 0) { + return 0; + } + + return _.sum(data) / data.length; +} + +function computeVariance({ data }: { data: number[] }) { + const mean = computeAverage({ data }); + + const squaredDiffs = data.map((value) => Math.pow(value - mean, 2)); + + return computeAverage({ data: squaredDiffs }); +} + +function arrayToMarkdownTable({ data, headerMap = {} }: { data: unknown[]; headerMap?: Record }) { + if (!Array.isArray(data) || data.length === 0) { + return ''; + } + + const headers = Object.keys(data[0]); + const rows = data.map((obj) => Object.values(obj)); + + const headerRow = `| ${headers.map((header) => headerMap[header] ?? header).join(' | ')} |`; + const separatorRow = `| ${headers.map(() => '---').join(' | ')} |`; + const dataRows = rows.map((row) => `| ${row.join(' | ')} |`).join('\n'); + + return `${headerRow}\n${separatorRow}\n${dataRows}`; +} diff --git a/src/tools/benchmark-builder/benchmark-builder.vue b/src/tools/benchmark-builder/benchmark-builder.vue new file mode 100644 index 00000000..387da192 --- /dev/null +++ b/src/tools/benchmark-builder/benchmark-builder.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/src/tools/benchmark-builder/dynamic-values.vue b/src/tools/benchmark-builder/dynamic-values.vue new file mode 100644 index 00000000..70268aed --- /dev/null +++ b/src/tools/benchmark-builder/dynamic-values.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/tools/benchmark-builder/index.ts b/src/tools/benchmark-builder/index.ts new file mode 100644 index 00000000..b9dcf114 --- /dev/null +++ b/src/tools/benchmark-builder/index.ts @@ -0,0 +1,11 @@ +import { SpeedFilled } from '@vicons/material'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Benchmark builder', + path: '/benchmark-builder', + description: 'Easily compare execution time of tasks with this very simple online benchmark builder.', + keywords: ['benchmark', 'builder', 'execution', 'duration', 'mean', 'variance'], + component: () => import('./benchmark-builder.vue'), + icon: SpeedFilled, +}); diff --git a/src/tools/index.ts b/src/tools/index.ts index 2a213011..29d32422 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,6 +1,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; +import { tool as benchmarkBuilder } from './benchmark-builder'; import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator'; import { tool as dockerRunToDockerComposeConverter } from './docker-run-to-docker-compose-converter'; import { tool as htmlWysiwygEditor } from './html-wysiwyg-editor'; @@ -107,7 +108,7 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Measurement', - components: [chronometer, temperatureConverter], + components: [chronometer, temperatureConverter, benchmarkBuilder], }, { name: 'Text',