Skip to content

Commit 313b4f3

Browse files
Iteration 155: DataFrameExpanding std/var/sum/count/median/apply + TZDatetimeIndex extra + TimedeltaIndex toStrings
Run: https://github.com/githubnext/tsessebe/actions/runs/24567781388 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 86d054b commit 313b4f3

10 files changed

Lines changed: 374 additions & 0 deletions
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Benchmark: DataFrame.expanding().median() and .apply(fn) on 10k-row DataFrame."""
2+
import pandas as pd
3+
import numpy as np
4+
import json
5+
import time
6+
7+
ROWS = 10_000
8+
WARMUP = 2
9+
ITERATIONS = 5
10+
11+
a = np.sin(np.arange(ROWS) * 0.05) * 100
12+
b = np.cos(np.arange(ROWS) * 0.05) * 80
13+
df = pd.DataFrame({"a": a, "b": b})
14+
15+
sum_fn = lambda x: x.sum()
16+
17+
for _ in range(WARMUP):
18+
df.expanding().median()
19+
df.expanding().apply(sum_fn, raw=True)
20+
21+
start = time.perf_counter()
22+
for _ in range(ITERATIONS):
23+
df.expanding().median()
24+
df.expanding().apply(sum_fn, raw=True)
25+
total = time.perf_counter() - start
26+
27+
print(json.dumps({
28+
"function": "dataframe_expanding_median_apply",
29+
"mean_ms": total / ITERATIONS * 1000,
30+
"iterations": ITERATIONS,
31+
"total_ms": total * 1000,
32+
}))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Benchmark: DataFrame.expanding().std() and .var() on 10k-row DataFrame."""
2+
import pandas as pd
3+
import numpy as np
4+
import json
5+
import time
6+
7+
ROWS = 10_000
8+
WARMUP = 3
9+
ITERATIONS = 10
10+
11+
a = np.sin(np.arange(ROWS) * 0.01) * 100
12+
b = np.cos(np.arange(ROWS) * 0.01) * 50
13+
df = pd.DataFrame({"a": a, "b": b})
14+
15+
for _ in range(WARMUP):
16+
df.expanding().std()
17+
df.expanding().var()
18+
19+
start = time.perf_counter()
20+
for _ in range(ITERATIONS):
21+
df.expanding().std()
22+
df.expanding().var()
23+
total = time.perf_counter() - start
24+
25+
print(json.dumps({
26+
"function": "dataframe_expanding_std_var",
27+
"mean_ms": total / ITERATIONS * 1000,
28+
"iterations": ITERATIONS,
29+
"total_ms": total * 1000,
30+
}))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Benchmark: DataFrame.expanding().sum() and .count() on 10k-row DataFrame."""
2+
import pandas as pd
3+
import numpy as np
4+
import json
5+
import time
6+
7+
ROWS = 10_000
8+
WARMUP = 3
9+
ITERATIONS = 10
10+
11+
a = (np.arange(ROWS) % 100) * 1.5
12+
b = (np.arange(ROWS) % 50) * 2.0
13+
df = pd.DataFrame({"a": a, "b": b})
14+
15+
for _ in range(WARMUP):
16+
df.expanding().sum()
17+
df.expanding().count()
18+
19+
start = time.perf_counter()
20+
for _ in range(ITERATIONS):
21+
df.expanding().sum()
22+
df.expanding().count()
23+
total = time.perf_counter() - start
24+
25+
print(json.dumps({
26+
"function": "dataframe_expanding_sum_count",
27+
"mean_ms": total / ITERATIONS * 1000,
28+
"iterations": ITERATIONS,
29+
"total_ms": total * 1000,
30+
}))
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Benchmark: TimedeltaIndex.astype(str), .to_numpy(), element access, rename
2+
on 10k-element TimedeltaIndex."""
3+
import pandas as pd
4+
import numpy as np
5+
import json
6+
import time
7+
8+
SIZE = 10_000
9+
WARMUP = 5
10+
ITERATIONS = 50
11+
12+
deltas = pd.to_timedelta(
13+
[(i % 365) * 24 * 3600 + (i % 24) * 3600 + (i % 60) * 60 for i in range(SIZE)],
14+
unit="s",
15+
)
16+
idx = pd.TimedeltaIndex(deltas, name="duration")
17+
18+
for _ in range(WARMUP):
19+
idx.astype(str)
20+
idx.to_numpy()
21+
idx[0]
22+
idx[-1]
23+
idx.rename("elapsed")
24+
25+
start = time.perf_counter()
26+
for _ in range(ITERATIONS):
27+
idx.astype(str)
28+
idx.to_numpy()
29+
idx[0]
30+
idx[-1]
31+
idx.rename("elapsed")
32+
total = time.perf_counter() - start
33+
34+
print(json.dumps({
35+
"function": "timedelta_index_tostrings",
36+
"mean_ms": total / ITERATIONS * 1000,
37+
"iterations": ITERATIONS,
38+
"total_ms": total * 1000,
39+
}))
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Benchmark: tz-aware DatetimeIndex — slice, concat, min/max, tz_convert,
2+
tz_localize(None), and array conversions on 10k-element index."""
3+
import pandas as pd
4+
import numpy as np
5+
import json
6+
import time
7+
8+
SIZE = 10_000
9+
WARMUP = 3
10+
ITERATIONS = 20
11+
12+
naive = pd.date_range("2024-01-01", periods=SIZE, freq="h")
13+
tz_idx = naive.tz_localize("America/New_York")
14+
half = SIZE // 2
15+
16+
for _ in range(WARMUP):
17+
tz_idx[:half]
18+
tz_idx[:half].append(tz_idx[half:])
19+
tz_idx[0]
20+
tz_idx.to_list()
21+
tz_idx.asi8
22+
tz_idx.min()
23+
tz_idx.max()
24+
tz_idx.tz_convert("UTC")
25+
tz_idx.tz_localize(None)
26+
27+
start = time.perf_counter()
28+
for _ in range(ITERATIONS):
29+
tz_idx[:half]
30+
tz_idx[:half].append(tz_idx[half:])
31+
tz_idx[0]
32+
tz_idx.to_list()
33+
tz_idx.asi8
34+
tz_idx.min()
35+
tz_idx.max()
36+
tz_idx.tz_convert("UTC")
37+
tz_idx.tz_localize(None)
38+
total = time.perf_counter() - start
39+
40+
print(json.dumps({
41+
"function": "tz_datetime_index_extra",
42+
"mean_ms": total / ITERATIONS * 1000,
43+
"iterations": ITERATIONS,
44+
"total_ms": total * 1000,
45+
}))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Benchmark: DataFrameExpanding.median() and .apply(fn) on 10k-row DataFrame.
3+
* Outputs JSON: {"function": "dataframe_expanding_median_apply", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame } from "../../src/index.js";
6+
7+
const ROWS = 10_000;
8+
const WARMUP = 2;
9+
const ITERATIONS = 5;
10+
11+
const a = Array.from({ length: ROWS }, (_, i) => Math.sin(i * 0.05) * 100);
12+
const b = Array.from({ length: ROWS }, (_, i) => Math.cos(i * 0.05) * 80);
13+
const df = DataFrame.fromColumns({ a, b });
14+
15+
const sumFn = (vals: readonly number[]) => vals.reduce((acc, v) => acc + v, 0);
16+
17+
for (let i = 0; i < WARMUP; i++) {
18+
df.expanding().median();
19+
df.expanding().apply(sumFn);
20+
}
21+
22+
const start = performance.now();
23+
for (let i = 0; i < ITERATIONS; i++) {
24+
df.expanding().median();
25+
df.expanding().apply(sumFn);
26+
}
27+
const total = performance.now() - start;
28+
29+
console.log(
30+
JSON.stringify({
31+
function: "dataframe_expanding_median_apply",
32+
mean_ms: total / ITERATIONS,
33+
iterations: ITERATIONS,
34+
total_ms: total,
35+
}),
36+
);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Benchmark: DataFrameExpanding.std() and .var() on 10k-row DataFrame.
3+
* Outputs JSON: {"function": "dataframe_expanding_std_var", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame } from "../../src/index.js";
6+
7+
const ROWS = 10_000;
8+
const WARMUP = 3;
9+
const ITERATIONS = 10;
10+
11+
const a = Array.from({ length: ROWS }, (_, i) => Math.sin(i * 0.01) * 100);
12+
const b = Array.from({ length: ROWS }, (_, i) => Math.cos(i * 0.01) * 50);
13+
const df = DataFrame.fromColumns({ a, b });
14+
15+
for (let i = 0; i < WARMUP; i++) {
16+
df.expanding().std();
17+
df.expanding().var();
18+
}
19+
20+
const start = performance.now();
21+
for (let i = 0; i < ITERATIONS; i++) {
22+
df.expanding().std();
23+
df.expanding().var();
24+
}
25+
const total = performance.now() - start;
26+
27+
console.log(
28+
JSON.stringify({
29+
function: "dataframe_expanding_std_var",
30+
mean_ms: total / ITERATIONS,
31+
iterations: ITERATIONS,
32+
total_ms: total,
33+
}),
34+
);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Benchmark: DataFrameExpanding.sum() and .count() on 10k-row DataFrame.
3+
* Outputs JSON: {"function": "dataframe_expanding_sum_count", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame } from "../../src/index.js";
6+
7+
const ROWS = 10_000;
8+
const WARMUP = 3;
9+
const ITERATIONS = 10;
10+
11+
const a = Array.from({ length: ROWS }, (_, i) => (i % 100) * 1.5);
12+
const b = Array.from({ length: ROWS }, (_, i) => (i % 50) * 2.0);
13+
const df = DataFrame.fromColumns({ a, b });
14+
15+
for (let i = 0; i < WARMUP; i++) {
16+
df.expanding().sum();
17+
df.expanding().count();
18+
}
19+
20+
const start = performance.now();
21+
for (let i = 0; i < ITERATIONS; i++) {
22+
df.expanding().sum();
23+
df.expanding().count();
24+
}
25+
const total = performance.now() - start;
26+
27+
console.log(
28+
JSON.stringify({
29+
function: "dataframe_expanding_sum_count",
30+
mean_ms: total / ITERATIONS,
31+
iterations: ITERATIONS,
32+
total_ms: total,
33+
}),
34+
);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Benchmark: TimedeltaIndex.toStrings(), .toArray(), .at(), .rename() on 10k-element index.
3+
* Outputs JSON: {"function": "timedelta_index_tostrings", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Timedelta, TimedeltaIndex } from "../../src/index.js";
6+
7+
const SIZE = 10_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 50;
10+
11+
const deltas = Array.from({ length: SIZE }, (_, i) =>
12+
Timedelta.fromComponents({ days: i % 365, hours: i % 24, minutes: i % 60 }),
13+
);
14+
const idx = TimedeltaIndex.fromTimedeltas(deltas, "duration");
15+
16+
for (let i = 0; i < WARMUP; i++) {
17+
idx.toStrings();
18+
idx.toArray();
19+
idx.at(0);
20+
idx.at(SIZE - 1);
21+
idx.rename("elapsed");
22+
}
23+
24+
const start = performance.now();
25+
for (let i = 0; i < ITERATIONS; i++) {
26+
idx.toStrings();
27+
idx.toArray();
28+
idx.at(0);
29+
idx.at(SIZE - 1);
30+
idx.rename("elapsed");
31+
}
32+
const total = performance.now() - start;
33+
34+
console.log(
35+
JSON.stringify({
36+
function: "timedelta_index_tostrings",
37+
mean_ms: total / ITERATIONS,
38+
iterations: ITERATIONS,
39+
total_ms: total,
40+
}),
41+
);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Benchmark: TZDatetimeIndex — slice, concat, at, toArray, toTimestamps, min, max,
3+
* tz_convert (instance method), tz_localize_none on 10k-element TZDatetimeIndex.
4+
* Outputs JSON: {"function": "tz_datetime_index_extra", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { date_range, tz_localize } from "../../src/index.js";
7+
8+
const SIZE = 10_000;
9+
const WARMUP = 3;
10+
const ITERATIONS = 20;
11+
12+
const naive = date_range({ start: "2024-01-01", periods: SIZE, freq: "h" });
13+
const tzIdx = tz_localize(naive, "America/New_York");
14+
const halfSize = Math.floor(SIZE / 2);
15+
16+
for (let i = 0; i < WARMUP; i++) {
17+
tzIdx.slice(0, halfSize);
18+
const half1 = tzIdx.slice(0, halfSize);
19+
const half2 = tzIdx.slice(halfSize);
20+
half1.concat(half2);
21+
tzIdx.at(0);
22+
tzIdx.toArray();
23+
tzIdx.toTimestamps();
24+
tzIdx.min();
25+
tzIdx.max();
26+
tzIdx.tz_convert("UTC");
27+
tzIdx.tz_localize_none();
28+
}
29+
30+
const start = performance.now();
31+
for (let i = 0; i < ITERATIONS; i++) {
32+
tzIdx.slice(0, halfSize);
33+
const half1 = tzIdx.slice(0, halfSize);
34+
const half2 = tzIdx.slice(halfSize);
35+
half1.concat(half2);
36+
tzIdx.at(0);
37+
tzIdx.toArray();
38+
tzIdx.toTimestamps();
39+
tzIdx.min();
40+
tzIdx.max();
41+
tzIdx.tz_convert("UTC");
42+
tzIdx.tz_localize_none();
43+
}
44+
const total = performance.now() - start;
45+
46+
console.log(
47+
JSON.stringify({
48+
function: "tz_datetime_index_extra",
49+
mean_ms: total / ITERATIONS,
50+
iterations: ITERATIONS,
51+
total_ms: total,
52+
}),
53+
);

0 commit comments

Comments
 (0)