From d818f6b4fdba113fa78a4c893ee0b7d3a519bb6f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 13:31:45 +0000 Subject: [PATCH 1/2] [Autoloop: perf-comparison] Iteration 318: add timedelta_range and combine benchmark pairs Run: https://github.com/githubnext/tsb/actions/runs/25963034091 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- benchmarks/pandas/bench_combine.py | 34 +++++++++++++++++ benchmarks/pandas/bench_timedelta_range.py | 28 ++++++++++++++ benchmarks/tsb/bench_combine.ts | 44 ++++++++++++++++++++++ benchmarks/tsb/bench_timedelta_range.ts | 36 ++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 benchmarks/pandas/bench_combine.py create mode 100644 benchmarks/pandas/bench_timedelta_range.py create mode 100644 benchmarks/tsb/bench_combine.ts create mode 100644 benchmarks/tsb/bench_timedelta_range.ts diff --git a/benchmarks/pandas/bench_combine.py b/benchmarks/pandas/bench_combine.py new file mode 100644 index 00000000..82578228 --- /dev/null +++ b/benchmarks/pandas/bench_combine.py @@ -0,0 +1,34 @@ +"""Benchmark: Series.combine / DataFrame.combine — element-wise binary combine.""" +import json +import time +import pandas as pd +import numpy as np + +SIZE = 10_000 +WARMUP = 5 +ITERATIONS = 100 + +a = pd.Series(range(SIZE)) +b = pd.Series(range(SIZE, 0, -1)) + +df_a = pd.DataFrame({"x": range(SIZE), "y": [i * 2 for i in range(SIZE)]}) +df_b = pd.DataFrame({"x": range(SIZE, 0, -1), "z": [i * 3 for i in range(SIZE)]}) + +add_fn = lambda p, q: p + q + +for _ in range(WARMUP): + a.combine(b, add_fn, fill_value=0) + df_a.combine(df_b, add_fn, fill_value=0) + +start = time.perf_counter() +for _ in range(ITERATIONS): + a.combine(b, add_fn, fill_value=0) + df_a.combine(df_b, add_fn, fill_value=0) +total = (time.perf_counter() - start) * 1000 + +print(json.dumps({ + "function": "combine", + "mean_ms": total / ITERATIONS, + "iterations": ITERATIONS, + "total_ms": total, +})) diff --git a/benchmarks/pandas/bench_timedelta_range.py b/benchmarks/pandas/bench_timedelta_range.py new file mode 100644 index 00000000..a68dc5ad --- /dev/null +++ b/benchmarks/pandas/bench_timedelta_range.py @@ -0,0 +1,28 @@ +"""Benchmark: pd.timedelta_range — evenly-spaced TimedeltaIndex factory.""" +import json +import time +import pandas as pd + +SIZE = 1_000 +WARMUP = 5 +ITERATIONS = 200 + +# Warm-up: three usage patterns +for _ in range(WARMUP): + pd.timedelta_range(start="0 days", periods=SIZE, freq="h") + pd.timedelta_range(start="0 days", end=f"{SIZE} days", freq="D") + pd.timedelta_range(start="0 days", end="10 days", periods=SIZE) + +start = time.perf_counter() +for _ in range(ITERATIONS): + pd.timedelta_range(start="0 days", periods=SIZE, freq="h") + pd.timedelta_range(start="0 days", end=f"{SIZE} days", freq="D") + pd.timedelta_range(start="0 days", end="10 days", periods=SIZE) +total = (time.perf_counter() - start) * 1000 + +print(json.dumps({ + "function": "timedelta_range", + "mean_ms": total / ITERATIONS, + "iterations": ITERATIONS, + "total_ms": total, +})) diff --git a/benchmarks/tsb/bench_combine.ts b/benchmarks/tsb/bench_combine.ts new file mode 100644 index 00000000..c5f161d0 --- /dev/null +++ b/benchmarks/tsb/bench_combine.ts @@ -0,0 +1,44 @@ +/** + * Benchmark: combineSeries / combineDataFrame — element-wise binary combine. + * Outputs JSON: {"function": "combine", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ +import { Series, DataFrame, combineSeries, combineDataFrame } from "../../src/index.js"; + +const SIZE = 10_000; +const WARMUP = 5; +const ITERATIONS = 100; + +const a = new Series({ data: Array.from({ length: SIZE }, (_, i) => i), index: Array.from({ length: SIZE }, (_, i) => i) }); +const b = new Series({ data: Array.from({ length: SIZE }, (_, i) => SIZE - i), index: Array.from({ length: SIZE }, (_, i) => i) }); + +const dfA = DataFrame.fromColumns({ + x: Array.from({ length: SIZE }, (_, i) => i), + y: Array.from({ length: SIZE }, (_, i) => i * 2), +}); +const dfB = DataFrame.fromColumns({ + x: Array.from({ length: SIZE }, (_, i) => SIZE - i), + z: Array.from({ length: SIZE }, (_, i) => i * 3), +}); + +const addFn = (p: unknown, q: unknown) => (p as number) + (q as number); + +for (let i = 0; i < WARMUP; i++) { + combineSeries(a, b, addFn, 0); + combineDataFrame(dfA, dfB, addFn, { fillValue: 0 }); +} + +const start = performance.now(); +for (let i = 0; i < ITERATIONS; i++) { + combineSeries(a, b, addFn, 0); + combineDataFrame(dfA, dfB, addFn, { fillValue: 0 }); +} +const total = performance.now() - start; + +console.log( + JSON.stringify({ + function: "combine", + mean_ms: total / ITERATIONS, + iterations: ITERATIONS, + total_ms: total, + }), +); diff --git a/benchmarks/tsb/bench_timedelta_range.ts b/benchmarks/tsb/bench_timedelta_range.ts new file mode 100644 index 00000000..13784008 --- /dev/null +++ b/benchmarks/tsb/bench_timedelta_range.ts @@ -0,0 +1,36 @@ +/** + * Benchmark: timedelta_range — evenly-spaced TimedeltaIndex factory. + * Outputs JSON: {"function": "timedelta_range", "mean_ms": ..., "iterations": ..., "total_ms": ...} + */ +import { timedelta_range } from "../../src/index.js"; + +const SIZE = 1_000; +const WARMUP = 5; +const ITERATIONS = 200; + +// Warm-up: three usage patterns +for (let i = 0; i < WARMUP; i++) { + // start + periods + freq + timedelta_range({ start: "0 days", periods: SIZE, freq: "H" }); + // start + end + freq + timedelta_range({ start: "0 days", end: `${SIZE} days`, freq: "D" }); + // start + end + periods (linspace) + timedelta_range({ start: "0 days", end: "10 days", periods: SIZE }); +} + +const start = performance.now(); +for (let i = 0; i < ITERATIONS; i++) { + timedelta_range({ start: "0 days", periods: SIZE, freq: "H" }); + timedelta_range({ start: "0 days", end: `${SIZE} days`, freq: "D" }); + timedelta_range({ start: "0 days", end: "10 days", periods: SIZE }); +} +const total = performance.now() - start; + +console.log( + JSON.stringify({ + function: "timedelta_range", + mean_ms: total / ITERATIONS, + iterations: ITERATIONS, + total_ms: total, + }), +); From d36e8fabd3a870b52952b9661090dbbfdbd068b3 Mon Sep 17 00:00:00 2001 From: Russell Horton Date: Sat, 16 May 2026 06:50:13 -0700 Subject: [PATCH 2/2] chore: trigger CI [evergreen]