Skip to content

Commit 5899214

Browse files
Iteration 144: Add 8 benchmark pairs (445 total, +8 vs best 437)
Added pairs: period_arithmetic (Period.add/diff/compareTo/contains), period_index_methods (PeriodIndex.shift/sort/unique/toDatetimeStart/toDatetimeEnd), dt_total_seconds (DatetimeAccessor.total_seconds), timedelta_index_ops (TimedeltaIndex.sort/unique/shift/filter/min/max), interval_overlaps (Interval.overlaps/IntervalIndex.overlaps), describe_opts (describe with percentiles/include options), merge_index_join (merge with left_index/right_index), to_json_orient (toJson with records/split/columns/values orient options). Run: https://github.com/githubnext/tsessebe/actions/runs/24549838166 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a84aca2 commit 5899214

16 files changed

Lines changed: 559 additions & 0 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Benchmark: DataFrame.describe() with percentiles / include options on 100k-row DataFrame."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 100_000
7+
WARMUP = 3
8+
ITERATIONS = 20
9+
10+
df = pd.DataFrame({
11+
"a": np.arange(SIZE) * 1.5,
12+
"b": (np.arange(SIZE) % 1000) * 0.7,
13+
"label": [f"cat_{i % 10}" for i in range(SIZE)],
14+
"flag": np.arange(SIZE) % 2 == 0,
15+
})
16+
17+
for _ in range(WARMUP):
18+
df.describe(percentiles=[0.1, 0.25, 0.5, 0.75, 0.9])
19+
df.describe(include="all")
20+
df.describe(include=[object])
21+
22+
times = []
23+
for _ in range(ITERATIONS):
24+
t0 = time.perf_counter()
25+
df.describe(percentiles=[0.1, 0.25, 0.5, 0.75, 0.9])
26+
df.describe(include="all")
27+
df.describe(include=[object])
28+
times.append((time.perf_counter() - t0) * 1000)
29+
30+
total_ms = sum(times)
31+
print(json.dumps({"function": "describe_opts", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Benchmark: Series.dt.total_seconds() — epoch-second conversion on 100k datetime Series."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 100_000
7+
WARMUP = 5
8+
ITERATIONS = 50
9+
10+
base = pd.Timestamp("2020-01-01T00:00:00Z")
11+
dates = pd.date_range(start=base, periods=SIZE, freq="min")
12+
s = pd.Series(dates)
13+
14+
for _ in range(WARMUP):
15+
(s - pd.Timestamp("1970-01-01", tz="UTC")).dt.total_seconds()
16+
17+
times = []
18+
for _ in range(ITERATIONS):
19+
t0 = time.perf_counter()
20+
(s - pd.Timestamp("1970-01-01", tz="UTC")).dt.total_seconds()
21+
times.append((time.perf_counter() - t0) * 1000)
22+
23+
total_ms = sum(times)
24+
print(json.dumps({"function": "dt_total_seconds", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Benchmark: Interval.overlaps / IntervalIndex.overlaps — overlap checks on 1k intervals."""
2+
import json, time
3+
import pandas as pd
4+
5+
SIZE = 1_000
6+
WARMUP = 5
7+
ITERATIONS = 50
8+
9+
intervals = [pd.Interval(i, i + 2) for i in range(SIZE)]
10+
breaks = list(range(SIZE + 1))
11+
idx = pd.IntervalIndex.from_breaks(breaks)
12+
query = pd.Interval(250, 750)
13+
14+
for _ in range(WARMUP):
15+
for iv in intervals[:50]:
16+
iv.overlaps(query)
17+
idx.overlaps(query)
18+
19+
times = []
20+
for _ in range(ITERATIONS):
21+
t0 = time.perf_counter()
22+
for iv in intervals:
23+
iv.overlaps(query)
24+
idx.overlaps(query)
25+
times.append((time.perf_counter() - t0) * 1000)
26+
27+
total_ms = sum(times)
28+
print(json.dumps({"function": "interval_overlaps", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Benchmark: merge with left_index / right_index options on 10k-row DataFrames."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 10_000
7+
WARMUP = 5
8+
ITERATIONS = 30
9+
10+
left = pd.DataFrame({"val_a": np.arange(SIZE) * 1.5})
11+
right = pd.DataFrame({"val_b": np.arange(SIZE) * 2.0})
12+
13+
for _ in range(WARMUP):
14+
pd.merge(left, right, left_index=True, right_index=True, how="inner")
15+
pd.merge(left, right, left_index=True, right_index=True, how="outer")
16+
pd.merge(left, right, left_index=True, right_index=True, how="left")
17+
18+
times = []
19+
for _ in range(ITERATIONS):
20+
t0 = time.perf_counter()
21+
pd.merge(left, right, left_index=True, right_index=True, how="inner")
22+
pd.merge(left, right, left_index=True, right_index=True, how="outer")
23+
pd.merge(left, right, left_index=True, right_index=True, how="left")
24+
times.append((time.perf_counter() - t0) * 1000)
25+
26+
total_ms = sum(times)
27+
print(json.dumps({"function": "merge_index_join", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Benchmark: Period.add / diff / compareTo / contains — Period arithmetic on 1k periods."""
2+
import json, time
3+
import pandas as pd
4+
5+
SIZE = 1_000
6+
WARMUP = 5
7+
ITERATIONS = 50
8+
9+
base = pd.Period("2020-01-01", freq="D")
10+
periods = [base + i for i in range(SIZE)]
11+
other = base + 500
12+
13+
for _ in range(WARMUP):
14+
for p in periods[:50]:
15+
p + 10
16+
p - other
17+
p < other
18+
p.start_time
19+
20+
times = []
21+
for _ in range(ITERATIONS):
22+
t0 = time.perf_counter()
23+
for p in periods:
24+
p + 10
25+
p - other
26+
p < other
27+
p.start_time
28+
times.append((time.perf_counter() - t0) * 1000)
29+
30+
total_ms = sum(times)
31+
print(json.dumps({"function": "period_arithmetic", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Benchmark: PeriodIndex.shift / sort_values / unique / to_timestamp — PeriodIndex operations on 1k periods."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 1_000
7+
WARMUP = 5
8+
ITERATIONS = 50
9+
10+
base = pd.Period("2020-01-01", freq="D")
11+
shuffled = [base + ((i * 7) % SIZE) for i in range(SIZE)]
12+
idx = pd.PeriodIndex(shuffled)
13+
14+
for _ in range(WARMUP):
15+
idx.shift(30)
16+
idx.sort_values()
17+
idx.unique()
18+
idx.to_timestamp(how="start")
19+
idx.to_timestamp(how="end")
20+
21+
times = []
22+
for _ in range(ITERATIONS):
23+
t0 = time.perf_counter()
24+
idx.shift(30)
25+
idx.sort_values()
26+
idx.unique()
27+
idx.to_timestamp(how="start")
28+
idx.to_timestamp(how="end")
29+
times.append((time.perf_counter() - t0) * 1000)
30+
31+
total_ms = sum(times)
32+
print(json.dumps({"function": "period_index_methods", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Benchmark: TimedeltaIndex sort / unique / shift / min / max on 1k-element index."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 1_000
7+
WARMUP = 5
8+
ITERATIONS = 100
9+
10+
deltas = [pd.Timedelta(days=(i * 13) % 365, hours=i % 24) for i in range(SIZE)]
11+
idx = pd.TimedeltaIndex(deltas)
12+
shift_by = pd.Timedelta(days=1)
13+
threshold = pd.Timedelta(days=100)
14+
15+
for _ in range(WARMUP):
16+
idx.sort_values()
17+
idx.unique()
18+
idx + shift_by
19+
idx[idx < threshold]
20+
idx.min()
21+
idx.max()
22+
23+
times = []
24+
for _ in range(ITERATIONS):
25+
t0 = time.perf_counter()
26+
idx.sort_values()
27+
idx.unique()
28+
idx + shift_by
29+
idx[idx < threshold]
30+
idx.min()
31+
idx.max()
32+
times.append((time.perf_counter() - t0) * 1000)
33+
34+
total_ms = sum(times)
35+
print(json.dumps({"function": "timedelta_index_ops", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Benchmark: DataFrame.to_json() with different orient options on 10k-row DataFrame."""
2+
import json, time
3+
import pandas as pd
4+
import numpy as np
5+
6+
SIZE = 10_000
7+
WARMUP = 3
8+
ITERATIONS = 20
9+
10+
df = pd.DataFrame({
11+
"id": np.arange(SIZE),
12+
"value": np.arange(SIZE) * 1.1,
13+
"label": [f"cat_{i % 10}" for i in range(SIZE)],
14+
})
15+
16+
for _ in range(WARMUP):
17+
df.to_json(orient="records")
18+
df.to_json(orient="split")
19+
df.to_json(orient="columns")
20+
df.to_json(orient="values")
21+
22+
times = []
23+
for _ in range(ITERATIONS):
24+
t0 = time.perf_counter()
25+
df.to_json(orient="records")
26+
df.to_json(orient="split")
27+
df.to_json(orient="columns")
28+
df.to_json(orient="values")
29+
times.append((time.perf_counter() - t0) * 1000)
30+
31+
total_ms = sum(times)
32+
print(json.dumps({"function": "to_json_orient", "mean_ms": round(total_ms / ITERATIONS, 3), "iterations": ITERATIONS, "total_ms": round(total_ms, 3)}))
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Benchmark: describe() with percentiles / include options on 100k-row DataFrame.
3+
* Outputs JSON: {"function": "describe_opts", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame, describe } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 3;
9+
const ITERATIONS = 20;
10+
11+
const df = DataFrame.fromColumns({
12+
a: Array.from({ length: SIZE }, (_, i) => i * 1.5),
13+
b: Array.from({ length: SIZE }, (_, i) => (i % 1000) * 0.7),
14+
label: Array.from({ length: SIZE }, (_, i) => `cat_${i % 10}`),
15+
flag: Array.from({ length: SIZE }, (_, i) => i % 2 === 0),
16+
});
17+
18+
for (let i = 0; i < WARMUP; i++) {
19+
describe(df, { percentiles: [0.1, 0.25, 0.5, 0.75, 0.9] });
20+
describe(df, { include: "all" });
21+
describe(df, { include: "object" });
22+
}
23+
24+
const start = performance.now();
25+
for (let i = 0; i < ITERATIONS; i++) {
26+
describe(df, { percentiles: [0.1, 0.25, 0.5, 0.75, 0.9] });
27+
describe(df, { include: "all" });
28+
describe(df, { include: "object" });
29+
}
30+
const total = performance.now() - start;
31+
32+
console.log(
33+
JSON.stringify({
34+
function: "describe_opts",
35+
mean_ms: total / ITERATIONS,
36+
iterations: ITERATIONS,
37+
total_ms: total,
38+
}),
39+
);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Benchmark: DatetimeAccessor.total_seconds — epoch-second conversion on 100k datetime Series.
3+
* Outputs JSON: {"function": "dt_total_seconds", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Series } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 50;
10+
11+
const base = new Date("2020-01-01T00:00:00Z").getTime();
12+
const dates = Array.from({ length: SIZE }, (_, i) => new Date(base + i * 60_000));
13+
const s = new Series({ data: dates });
14+
15+
for (let i = 0; i < WARMUP; i++) {
16+
s.dt.total_seconds();
17+
}
18+
19+
const start = performance.now();
20+
for (let i = 0; i < ITERATIONS; i++) {
21+
s.dt.total_seconds();
22+
}
23+
const total = performance.now() - start;
24+
25+
console.log(
26+
JSON.stringify({
27+
function: "dt_total_seconds",
28+
mean_ms: total / ITERATIONS,
29+
iterations: ITERATIONS,
30+
total_ms: total,
31+
}),
32+
);

0 commit comments

Comments
 (0)