From df1f761a2c7e7d6d08c1fd9b8a0175816d127ff3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:14:43 +0000 Subject: [PATCH] Iteration 44: Add 8 benchmark pairs (melt, rank, zscore, nlargest, expanding_mean, pearson_corr, to_csv, read_json) Run: https://github.com/githubnext/tsessebe/actions/runs/24363866146 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- benchmarks/pandas/bench_expanding_mean.py | 38 ++++++++++ benchmarks/pandas/bench_melt.py | 47 ++++++++++++ benchmarks/pandas/bench_nlargest.py | 39 ++++++++++ benchmarks/pandas/bench_pearson_corr.py | 38 ++++++++++ benchmarks/pandas/bench_rank.py | 38 ++++++++++ benchmarks/pandas/bench_read_json.py | 42 +++++++++++ benchmarks/pandas/bench_to_csv.py | 43 +++++++++++ benchmarks/pandas/bench_zscore.py | 41 +++++++++++ benchmarks/results.json | 90 ++++++++++++++++++++++- benchmarks/tsb/bench_expanding_mean.ts | 36 +++++++++ benchmarks/tsb/bench_melt.ts | 46 ++++++++++++ benchmarks/tsb/bench_nlargest.ts | 37 ++++++++++ benchmarks/tsb/bench_pearson_corr.ts | 37 ++++++++++ benchmarks/tsb/bench_rank.ts | 40 ++++++++++ benchmarks/tsb/bench_read_json.ts | 46 ++++++++++++ benchmarks/tsb/bench_to_csv.ts | 47 ++++++++++++ benchmarks/tsb/bench_zscore.ts | 36 +++++++++ 17 files changed, 740 insertions(+), 1 deletion(-) create mode 100644 benchmarks/pandas/bench_expanding_mean.py create mode 100644 benchmarks/pandas/bench_melt.py create mode 100644 benchmarks/pandas/bench_nlargest.py create mode 100644 benchmarks/pandas/bench_pearson_corr.py create mode 100644 benchmarks/pandas/bench_rank.py create mode 100644 benchmarks/pandas/bench_read_json.py create mode 100644 benchmarks/pandas/bench_to_csv.py create mode 100644 benchmarks/pandas/bench_zscore.py create mode 100644 benchmarks/tsb/bench_expanding_mean.ts create mode 100644 benchmarks/tsb/bench_melt.ts create mode 100644 benchmarks/tsb/bench_nlargest.ts create mode 100644 benchmarks/tsb/bench_pearson_corr.ts create mode 100644 benchmarks/tsb/bench_rank.ts create mode 100644 benchmarks/tsb/bench_read_json.ts create mode 100644 benchmarks/tsb/bench_to_csv.ts create mode 100644 benchmarks/tsb/bench_zscore.ts diff --git a/benchmarks/pandas/bench_expanding_mean.py b/benchmarks/pandas/bench_expanding_mean.py new file mode 100644 index 00000000..ff2071cc --- /dev/null +++ b/benchmarks/pandas/bench_expanding_mean.py @@ -0,0 +1,38 @@ +""" +Benchmark: Expanding mean + +Computes the expanding mean of a large numeric Series. +Outputs JSON: {"function": "expanding_mean", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +SIZE = 50_000 +WARMUP = 5 +ITERATIONS = 50 + +data = [i * 1.1 + 0.5 for i in range(SIZE)] +s = pd.Series(data) + +for _ in range(WARMUP): + s.expanding().mean() + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + s.expanding().mean() + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "expanding_mean", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_melt.py b/benchmarks/pandas/bench_melt.py new file mode 100644 index 00000000..7c766ce7 --- /dev/null +++ b/benchmarks/pandas/bench_melt.py @@ -0,0 +1,47 @@ +""" +Benchmark: DataFrame melt (unpivot) + +Creates a wide DataFrame and melts it into long format. +Outputs JSON: {"function": "melt", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +ROWS = 10_000 +WARMUP = 5 +ITERATIONS = 50 + + +def make_frame() -> pd.DataFrame: + return pd.DataFrame({ + "id": list(range(ROWS)), + "a": [i * 1.1 for i in range(ROWS)], + "b": [i * 2.2 for i in range(ROWS)], + "c": [i * 3.3 for i in range(ROWS)], + }) + + +df = make_frame() + +for _ in range(WARMUP): + df.melt(id_vars=["id"], value_vars=["a", "b", "c"]) + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + df.melt(id_vars=["id"], value_vars=["a", "b", "c"]) + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "melt", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_nlargest.py b/benchmarks/pandas/bench_nlargest.py new file mode 100644 index 00000000..542c5039 --- /dev/null +++ b/benchmarks/pandas/bench_nlargest.py @@ -0,0 +1,39 @@ +""" +Benchmark: Series nlargest + +Returns the N largest values from a large numeric Series. +Outputs JSON: {"function": "nlargest", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +SIZE = 100_000 +N = 100 +WARMUP = 5 +ITERATIONS = 50 + +data = [(i * 7919) % SIZE for i in range(SIZE)] +s = pd.Series(data) + +for _ in range(WARMUP): + s.nlargest(N) + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + s.nlargest(N) + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "nlargest", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_pearson_corr.py b/benchmarks/pandas/bench_pearson_corr.py new file mode 100644 index 00000000..55fed95f --- /dev/null +++ b/benchmarks/pandas/bench_pearson_corr.py @@ -0,0 +1,38 @@ +""" +Benchmark: Pearson correlation + +Computes the Pearson correlation coefficient between two large numeric Series. +Outputs JSON: {"function": "pearson_corr", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +SIZE = 100_000 +WARMUP = 5 +ITERATIONS = 50 + +x = pd.Series([i * 1.1 + 0.5 for i in range(SIZE)]) +y = pd.Series([i * 0.9 - 0.3 for i in range(SIZE)]) + +for _ in range(WARMUP): + x.corr(y, method="pearson") + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + x.corr(y, method="pearson") + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "pearson_corr", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_rank.py b/benchmarks/pandas/bench_rank.py new file mode 100644 index 00000000..e945b97b --- /dev/null +++ b/benchmarks/pandas/bench_rank.py @@ -0,0 +1,38 @@ +""" +Benchmark: Series rank + +Ranks a large numeric Series using average tie-breaking. +Outputs JSON: {"function": "rank", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +SIZE = 100_000 +WARMUP = 5 +ITERATIONS = 50 + +data = [float((i // 3) * 1.5) for i in range(SIZE)] +s = pd.Series(data) + +for _ in range(WARMUP): + s.rank(method="average") + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + s.rank(method="average") + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "rank", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_read_json.py b/benchmarks/pandas/bench_read_json.py new file mode 100644 index 00000000..f4917cf5 --- /dev/null +++ b/benchmarks/pandas/bench_read_json.py @@ -0,0 +1,42 @@ +""" +Benchmark: DataFrame read_json + +Parses a JSON string into a DataFrame (records orient). +Outputs JSON: {"function": "read_json", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time +import io + +import pandas as pd + +ROWS = 5_000 +WARMUP = 5 +ITERATIONS = 50 + +records = [ + {"id": i, "x": i * 1.1, "y": i * 2.2, "label": f"item_{i % 100}"} + for i in range(ROWS) +] +json_str = json.dumps(records) + +for _ in range(WARMUP): + pd.read_json(io.StringIO(json_str)) + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + pd.read_json(io.StringIO(json_str)) + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "read_json", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_to_csv.py b/benchmarks/pandas/bench_to_csv.py new file mode 100644 index 00000000..7fc0ad2f --- /dev/null +++ b/benchmarks/pandas/bench_to_csv.py @@ -0,0 +1,43 @@ +""" +Benchmark: DataFrame to_csv + +Serializes a large DataFrame to a CSV string. +Outputs JSON: {"function": "to_csv", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time +import io + +import pandas as pd + +ROWS = 10_000 +WARMUP = 5 +ITERATIONS = 50 + +df = pd.DataFrame({ + "id": list(range(ROWS)), + "x": [i * 1.1 for i in range(ROWS)], + "y": [i * 2.2 for i in range(ROWS)], + "label": [f"item_{i % 100}" for i in range(ROWS)], +}) + +for _ in range(WARMUP): + df.to_csv(index=False) + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + df.to_csv(index=False) + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "to_csv", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/pandas/bench_zscore.py b/benchmarks/pandas/bench_zscore.py new file mode 100644 index 00000000..1d00760f --- /dev/null +++ b/benchmarks/pandas/bench_zscore.py @@ -0,0 +1,41 @@ +""" +Benchmark: Series zscore (z-score normalization) + +Computes the z-score of a large numeric Series. +Outputs JSON: {"function": "zscore", "mean_ms": ..., "iterations": ..., "total_ms": ...} +""" + +import json +import time + +import pandas as pd + +SIZE = 100_000 +WARMUP = 5 +ITERATIONS = 50 + +data = [i * 1.1 + 0.5 for i in range(SIZE)] +s = pd.Series(data) + +def zscore(series: pd.Series) -> pd.Series: + return (series - series.mean()) / series.std(ddof=1) + +for _ in range(WARMUP): + zscore(s) + +times: "list[float]" = [] +for _ in range(ITERATIONS): + start = time.perf_counter() + zscore(s) + end = time.perf_counter() + times.append((end - start) * 1000) + +total_ms = sum(times) +mean_ms = total_ms / ITERATIONS + +print(json.dumps({ + "function": "zscore", + "mean_ms": round(mean_ms, 3), + "iterations": ITERATIONS, + "total_ms": round(total_ms, 3), +})) diff --git a/benchmarks/results.json b/benchmarks/results.json index c883f334..0c506400 100644 --- a/benchmarks/results.json +++ b/benchmarks/results.json @@ -241,7 +241,95 @@ "total_ms": 92.12644899997713 }, "ratio": null + }, + { + "function": "melt", + "tsb": null, + "pandas": { + "function": "melt", + "mean_ms": 1.232, + "iterations": 50, + "total_ms": 61.579 + }, + "ratio": null + }, + { + "function": "rank", + "tsb": null, + "pandas": { + "function": "rank", + "mean_ms": 2.319, + "iterations": 50, + "total_ms": 115.947 + }, + "ratio": null + }, + { + "function": "zscore", + "tsb": null, + "pandas": { + "function": "zscore", + "mean_ms": 0.717, + "iterations": 50, + "total_ms": 35.832 + }, + "ratio": null + }, + { + "function": "nlargest", + "tsb": null, + "pandas": { + "function": "nlargest", + "mean_ms": 0.661, + "iterations": 50, + "total_ms": 33.043 + }, + "ratio": null + }, + { + "function": "expanding_mean", + "tsb": null, + "pandas": { + "function": "expanding_mean", + "mean_ms": 0.579, + "iterations": 50, + "total_ms": 28.939 + }, + "ratio": null + }, + { + "function": "pearson_corr", + "tsb": null, + "pandas": { + "function": "pearson_corr", + "mean_ms": 0.502, + "iterations": 50, + "total_ms": 25.122 + }, + "ratio": null + }, + { + "function": "to_csv", + "tsb": null, + "pandas": { + "function": "to_csv", + "mean_ms": 21.541, + "iterations": 50, + "total_ms": 1077.048 + }, + "ratio": null + }, + { + "function": "read_json", + "tsb": null, + "pandas": { + "function": "read_json", + "mean_ms": 7.39, + "iterations": 50, + "total_ms": 369.487 + }, + "ratio": null } ], - "timestamp": "2026-04-12T15:46:00Z" + "timestamp": "2026-04-13T19:58:00Z" } \ No newline at end of file diff --git a/benchmarks/tsb/bench_expanding_mean.ts b/benchmarks/tsb/bench_expanding_mean.ts new file mode 100644 index 00000000..9d71d3be --- /dev/null +++ b/benchmarks/tsb/bench_expanding_mean.ts @@ -0,0 +1,36 @@ +/** + * Benchmark: Expanding mean + * + * Computes the expanding mean of a large numeric Series. + * Outputs JSON: {"function": "expanding_mean", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { Series, Expanding } from "../../src/index.ts"; + +const SIZE = 50_000; +const WARMUP = 5; +const ITERATIONS = 50; + +const s = new Series({ data: Array.from({ length: SIZE }, (_, i) => i * 1.1 + 0.5) }); + +for (let i = 0; i < WARMUP; i++) { + new Expanding(s).mean(); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + new Expanding(s).mean(); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "expanding_mean", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_melt.ts b/benchmarks/tsb/bench_melt.ts new file mode 100644 index 00000000..2d182bca --- /dev/null +++ b/benchmarks/tsb/bench_melt.ts @@ -0,0 +1,46 @@ +/** + * Benchmark: DataFrame melt (unpivot) + * + * Creates a wide DataFrame and melts it into long format. + * Outputs JSON: {"function": "melt", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { DataFrame, melt } from "../../src/index.ts"; + +const ROWS = 10_000; +const WARMUP = 5; +const ITERATIONS = 50; + +function makeFrame(): DataFrame { + const data: Record = { + id: Array.from({ length: ROWS }, (_, i) => i), + a: Array.from({ length: ROWS }, (_, i) => i * 1.1), + b: Array.from({ length: ROWS }, (_, i) => i * 2.2), + c: Array.from({ length: ROWS }, (_, i) => i * 3.3), + }; + return new DataFrame({ data }); +} + +const df = makeFrame(); + +for (let i = 0; i < WARMUP; i++) { + melt(df, { idVars: ["id"], valueVars: ["a", "b", "c"] }); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + melt(df, { idVars: ["id"], valueVars: ["a", "b", "c"] }); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "melt", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_nlargest.ts b/benchmarks/tsb/bench_nlargest.ts new file mode 100644 index 00000000..d7d55cca --- /dev/null +++ b/benchmarks/tsb/bench_nlargest.ts @@ -0,0 +1,37 @@ +/** + * Benchmark: Series nlargest + * + * Returns the N largest values from a large numeric Series. + * Outputs JSON: {"function": "nlargest", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { Series, nlargestSeries } from "../../src/index.ts"; + +const SIZE = 100_000; +const N = 100; +const WARMUP = 5; +const ITERATIONS = 50; + +const s = new Series({ data: Array.from({ length: SIZE }, (_, i) => (i * 7919) % SIZE) }); + +for (let i = 0; i < WARMUP; i++) { + nlargestSeries(s, N); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + nlargestSeries(s, N); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "nlargest", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_pearson_corr.ts b/benchmarks/tsb/bench_pearson_corr.ts new file mode 100644 index 00000000..3b7f5ca6 --- /dev/null +++ b/benchmarks/tsb/bench_pearson_corr.ts @@ -0,0 +1,37 @@ +/** + * Benchmark: Pearson correlation + * + * Computes the Pearson correlation coefficient between two large numeric Series. + * Outputs JSON: {"function": "pearson_corr", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { Series, pearsonCorr } from "../../src/index.ts"; + +const SIZE = 100_000; +const WARMUP = 5; +const ITERATIONS = 50; + +const x = new Series({ data: Array.from({ length: SIZE }, (_, i) => i * 1.1 + 0.5) }); +const y = new Series({ data: Array.from({ length: SIZE }, (_, i) => i * 0.9 - 0.3) }); + +for (let i = 0; i < WARMUP; i++) { + pearsonCorr(x, y); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + pearsonCorr(x, y); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "pearson_corr", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_rank.ts b/benchmarks/tsb/bench_rank.ts new file mode 100644 index 00000000..a1c36b8b --- /dev/null +++ b/benchmarks/tsb/bench_rank.ts @@ -0,0 +1,40 @@ +/** + * Benchmark: Series rank + * + * Ranks a large numeric Series using average tie-breaking. + * Outputs JSON: {"function": "rank", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { Series, rankSeries } from "../../src/index.ts"; + +const SIZE = 100_000; +const WARMUP = 5; +const ITERATIONS = 50; + +function makeData(): readonly number[] { + return Array.from({ length: SIZE }, (_, i) => Math.floor(i / 3) * 1.5); +} + +const s = new Series({ data: Array.from(makeData()) }); + +for (let i = 0; i < WARMUP; i++) { + rankSeries(s, { method: "average" }); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + rankSeries(s, { method: "average" }); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "rank", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_read_json.ts b/benchmarks/tsb/bench_read_json.ts new file mode 100644 index 00000000..f916d9a5 --- /dev/null +++ b/benchmarks/tsb/bench_read_json.ts @@ -0,0 +1,46 @@ +/** + * Benchmark: DataFrame readJson + * + * Parses a JSON string into a DataFrame (records orient). + * Outputs JSON: {"function": "read_json", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { readJson } from "../../src/index.ts"; + +const ROWS = 5_000; +const WARMUP = 5; +const ITERATIONS = 50; + +function makeJsonString(): string { + const records = Array.from({ length: ROWS }, (_, i) => ({ + id: i, + x: i * 1.1, + y: i * 2.2, + label: `item_${i % 100}`, + })); + return JSON.stringify(records); +} + +const jsonStr = makeJsonString(); + +for (let i = 0; i < WARMUP; i++) { + readJson(jsonStr); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + readJson(jsonStr); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "read_json", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_to_csv.ts b/benchmarks/tsb/bench_to_csv.ts new file mode 100644 index 00000000..3e644350 --- /dev/null +++ b/benchmarks/tsb/bench_to_csv.ts @@ -0,0 +1,47 @@ +/** + * Benchmark: DataFrame toCsv + * + * Serializes a large DataFrame to a CSV string. + * Outputs JSON: {"function": "to_csv", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { DataFrame, toCsv } from "../../src/index.ts"; + +const ROWS = 10_000; +const WARMUP = 5; +const ITERATIONS = 50; + +function makeFrame(): DataFrame { + return new DataFrame({ + data: { + id: Array.from({ length: ROWS }, (_, i) => i), + x: Array.from({ length: ROWS }, (_, i) => i * 1.1), + y: Array.from({ length: ROWS }, (_, i) => i * 2.2), + label: Array.from({ length: ROWS }, (_, i) => `item_${i % 100}`), + }, + }); +} + +const df = makeFrame(); + +for (let i = 0; i < WARMUP; i++) { + toCsv(df); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + toCsv(df); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "to_csv", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +})); diff --git a/benchmarks/tsb/bench_zscore.ts b/benchmarks/tsb/bench_zscore.ts new file mode 100644 index 00000000..de27ec79 --- /dev/null +++ b/benchmarks/tsb/bench_zscore.ts @@ -0,0 +1,36 @@ +/** + * Benchmark: Series zscore (z-score normalization) + * + * Computes the z-score of a large numeric Series. + * Outputs JSON: {"function": "zscore", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ + +import { Series, zscore } from "../../src/index.ts"; + +const SIZE = 100_000; +const WARMUP = 5; +const ITERATIONS = 50; + +const s = new Series({ data: Array.from({ length: SIZE }, (_, i) => i * 1.1 + 0.5) }); + +for (let i = 0; i < WARMUP; i++) { + zscore(s); +} + +const times: number[] = []; +for (let i = 0; i < ITERATIONS; i++) { + const start = performance.now(); + zscore(s); + const end = performance.now(); + times.push(end - start); +} + +const totalMs = times.reduce((a, b) => a + b, 0); +const meanMs = totalMs / ITERATIONS; + +console.log(JSON.stringify({ + function: "zscore", + mean_ms: Math.round(meanMs * 1000) / 1000, + iterations: ITERATIONS, + total_ms: Math.round(totalMs * 1000) / 1000, +}));