Skip to content

Commit 7178c40

Browse files
Iteration 170: 5 new benchmark pairs (539 total, +5 vs branch 534)
Add cumulative ops and nan-aggregate benchmark pairs: - nancumops_extra: nanmedian, nancount, nanprod (previously unbenchmarked) - cumops_skipna: cumsum/cumprod with skipna=false option - dataframe_cumops_axis1: DataFrame cumsum/cumprod with axis=1 (row-wise) - series_cumops_nan: cumsum/cumprod/cummax/cummin on Series with NaN values - cummax_cummin_str: cummax/cummin on string Series Run: https://github.com/githubnext/tsessebe/actions/runs/24591536269 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f700047 commit 7178c40

10 files changed

Lines changed: 292 additions & 0 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Benchmark: Series.cummax() / cummin() on string Series of 10k elements.
3+
Outputs JSON: {"function": "cummax_cummin_str", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import pandas as pd
8+
9+
SIZE = 10_000
10+
WARMUP = 5
11+
ITERATIONS = 50
12+
13+
words = ["apple", "banana", "cherry", "date", "elderberry", "fig", "grape", "honeydew"]
14+
data = [words[i % len(words)] for i in range(SIZE)]
15+
s = pd.Series(data)
16+
17+
for _ in range(WARMUP):
18+
s.cummax()
19+
s.cummin()
20+
21+
start = time.perf_counter()
22+
for _ in range(ITERATIONS):
23+
s.cummax()
24+
s.cummin()
25+
total = (time.perf_counter() - start) * 1000
26+
27+
print(json.dumps({"function": "cummax_cummin_str", "mean_ms": total / ITERATIONS, "iterations": ITERATIONS, "total_ms": total}))
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Benchmark: cumsum / cumprod with skipna=False on 100k-element Series.
3+
Outputs JSON: {"function": "cumops_skipna", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import numpy as np
8+
import pandas as pd
9+
10+
SIZE = 100_000
11+
WARMUP = 5
12+
ITERATIONS = 20
13+
14+
data = [(i % 100) * 0.001 + 1 if i % 20 != 0 else float("nan") for i in range(SIZE)]
15+
s = pd.Series(data)
16+
17+
for _ in range(WARMUP):
18+
s.cumsum(skipna=False)
19+
s.cumprod(skipna=False)
20+
21+
start = time.perf_counter()
22+
for _ in range(ITERATIONS):
23+
s.cumsum(skipna=False)
24+
s.cumprod(skipna=False)
25+
total = (time.perf_counter() - start) * 1000
26+
27+
print(json.dumps({"function": "cumops_skipna", "mean_ms": total / ITERATIONS, "iterations": ITERATIONS, "total_ms": total}))
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Benchmark: DataFrame.cumsum(axis=1) / cumprod(axis=1) (row-wise) on 10k x 8 DataFrame.
3+
Outputs JSON: {"function": "dataframe_cumops_axis1", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import numpy as np
8+
import pandas as pd
9+
10+
ROWS = 10_000
11+
COLS = 8
12+
WARMUP = 3
13+
ITERATIONS = 20
14+
15+
data = {f"col{c}": ((np.arange(ROWS) + c) % 10) * 0.1 + 1 for c in range(COLS)}
16+
df = pd.DataFrame(data)
17+
18+
for _ in range(WARMUP):
19+
df.cumsum(axis=1)
20+
df.cumprod(axis=1)
21+
22+
start = time.perf_counter()
23+
for _ in range(ITERATIONS):
24+
df.cumsum(axis=1)
25+
df.cumprod(axis=1)
26+
total = (time.perf_counter() - start) * 1000
27+
28+
print(json.dumps({"function": "dataframe_cumops_axis1", "mean_ms": total / ITERATIONS, "iterations": ITERATIONS, "total_ms": total}))
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
Benchmark: np.nanmedian / nancount / np.nanprod — additional nan-ignoring aggregates on 100k array.
3+
Outputs JSON: {"function": "nancumops_extra", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import math
7+
import time
8+
import numpy as np
9+
10+
SIZE = 100_000
11+
WARMUP = 5
12+
ITERATIONS = 50
13+
14+
# Array with ~10% NaN values
15+
data = np.array([float("nan") if i % 10 == 0 else math.sin(i * 0.01) * 100 + 50 for i in range(SIZE)])
16+
17+
for _ in range(WARMUP):
18+
np.nanmedian(data)
19+
np.count_nonzero(~np.isnan(data))
20+
np.nanprod(data[:100]) # limit to 100 to avoid overflow
21+
22+
start = time.perf_counter()
23+
for _ in range(ITERATIONS):
24+
np.nanmedian(data)
25+
np.count_nonzero(~np.isnan(data))
26+
np.nanprod(data[:100])
27+
total = (time.perf_counter() - start) * 1000
28+
29+
print(json.dumps({"function": "nancumops_extra", "mean_ms": total / ITERATIONS, "iterations": ITERATIONS, "total_ms": total}))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Benchmark: cumsum / cumprod / cummax / cummin on 100k Series with NaN values.
3+
Outputs JSON: {"function": "series_cumops_nan", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import math
7+
import time
8+
import numpy as np
9+
import pandas as pd
10+
11+
SIZE = 100_000
12+
WARMUP = 5
13+
ITERATIONS = 20
14+
15+
raw = [float("nan") if i % 10 == 0 else math.sin(i * 0.01) * 50 + 100 for i in range(SIZE)]
16+
s = pd.Series(raw)
17+
18+
for _ in range(WARMUP):
19+
s.cumsum()
20+
s.cumprod()
21+
s.cummax()
22+
s.cummin()
23+
24+
start = time.perf_counter()
25+
for _ in range(ITERATIONS):
26+
s.cumsum()
27+
s.cumprod()
28+
s.cummax()
29+
s.cummin()
30+
total = (time.perf_counter() - start) * 1000
31+
32+
print(json.dumps({"function": "series_cumops_nan", "mean_ms": total / ITERATIONS, "iterations": ITERATIONS, "total_ms": total}))
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Benchmark: cummax / cummin on string Series of 10k elements.
3+
* Outputs JSON: {"function": "cummax_cummin_str", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Series, cummax, cummin } from "../../src/index.ts";
6+
7+
const SIZE = 10_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 50;
10+
11+
const words = ["apple", "banana", "cherry", "date", "elderberry", "fig", "grape", "honeydew"];
12+
const data: string[] = Array.from({ length: SIZE }, (_, i) => words[i % words.length]);
13+
const s = new Series({ data });
14+
15+
for (let i = 0; i < WARMUP; i++) {
16+
cummax(s);
17+
cummin(s);
18+
}
19+
20+
const start = performance.now();
21+
for (let i = 0; i < ITERATIONS; i++) {
22+
cummax(s);
23+
cummin(s);
24+
}
25+
const total = performance.now() - start;
26+
27+
console.log(JSON.stringify({ function: "cummax_cummin_str", mean_ms: total / ITERATIONS, iterations: ITERATIONS, total_ms: total }));
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Benchmark: cumsum / cumprod with skipna=false on 100k-element Series.
3+
* Outputs JSON: {"function": "cumops_skipna", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Series, cumsum, cumprod } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 20;
10+
11+
// Series with ~5% NaN values
12+
const data: (number | null)[] = Array.from({ length: SIZE }, (_, i) =>
13+
i % 20 === 0 ? null : (i % 100) * 0.001 + 1,
14+
);
15+
const s = new Series({ data });
16+
17+
for (let i = 0; i < WARMUP; i++) {
18+
cumsum(s, { skipna: false });
19+
cumprod(s, { skipna: false });
20+
}
21+
22+
const start = performance.now();
23+
for (let i = 0; i < ITERATIONS; i++) {
24+
cumsum(s, { skipna: false });
25+
cumprod(s, { skipna: false });
26+
}
27+
const total = performance.now() - start;
28+
29+
console.log(JSON.stringify({ function: "cumops_skipna", mean_ms: total / ITERATIONS, iterations: ITERATIONS, total_ms: total }));
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Benchmark: dataFrameCumsum / dataFrameCumprod with axis=1 (row-wise) on 10k x 8 DataFrame.
3+
* Outputs JSON: {"function": "dataframe_cumops_axis1", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame, dataFrameCumsum, dataFrameCumprod } from "../../src/index.ts";
6+
7+
const ROWS = 10_000;
8+
const COLS = 8;
9+
const WARMUP = 3;
10+
const ITERATIONS = 20;
11+
12+
const data: Record<string, number[]> = {};
13+
for (let c = 0; c < COLS; c++) {
14+
data[`col${c}`] = Array.from({ length: ROWS }, (_, i) => ((i + c) % 10) * 0.1 + 1);
15+
}
16+
const df = new DataFrame(data);
17+
18+
for (let i = 0; i < WARMUP; i++) {
19+
dataFrameCumsum(df, { axis: 1 });
20+
dataFrameCumprod(df, { axis: 1 });
21+
}
22+
23+
const start = performance.now();
24+
for (let i = 0; i < ITERATIONS; i++) {
25+
dataFrameCumsum(df, { axis: 1 });
26+
dataFrameCumprod(df, { axis: 1 });
27+
}
28+
const total = performance.now() - start;
29+
30+
console.log(JSON.stringify({ function: "dataframe_cumops_axis1", mean_ms: total / ITERATIONS, iterations: ITERATIONS, total_ms: total }));
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Benchmark: nanmedian / nancount / nanprod — additional nan-ignoring aggregates on 100k array.
3+
* Outputs JSON: {"function": "nancumops_extra", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { nanmedian, nancount, nanprod } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 50;
10+
11+
// Array with ~10% NaN values
12+
const data: (number | null)[] = Array.from({ length: SIZE }, (_, i) =>
13+
i % 10 === 0 ? null : Math.sin(i * 0.01) * 100 + 50,
14+
);
15+
16+
for (let i = 0; i < WARMUP; i++) {
17+
nanmedian(data);
18+
nancount(data);
19+
nanprod(data);
20+
}
21+
22+
const start = performance.now();
23+
for (let i = 0; i < ITERATIONS; i++) {
24+
nanmedian(data);
25+
nancount(data);
26+
nanprod(data);
27+
}
28+
const total = performance.now() - start;
29+
30+
console.log(JSON.stringify({ function: "nancumops_extra", mean_ms: total / ITERATIONS, iterations: ITERATIONS, total_ms: total }));
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Benchmark: cumsum / cumprod / cummax / cummin on 100k-element Series with NaN values (skipna=true).
3+
* Outputs JSON: {"function": "series_cumops_nan", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Series, cumsum, cumprod, cummax, cummin } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 20;
10+
11+
// ~10% NaN values
12+
const data: (number | null)[] = Array.from({ length: SIZE }, (_, i) =>
13+
i % 10 === 0 ? null : Math.sin(i * 0.01) * 50 + 100,
14+
);
15+
const s = new Series({ data });
16+
17+
for (let i = 0; i < WARMUP; i++) {
18+
cumsum(s);
19+
cumprod(s);
20+
cummax(s);
21+
cummin(s);
22+
}
23+
24+
const start = performance.now();
25+
for (let i = 0; i < ITERATIONS; i++) {
26+
cumsum(s);
27+
cumprod(s);
28+
cummax(s);
29+
cummin(s);
30+
}
31+
const total = performance.now() - start;
32+
33+
console.log(JSON.stringify({ function: "series_cumops_nan", mean_ms: total / ITERATIONS, iterations: ITERATIONS, total_ms: total }));

0 commit comments

Comments
 (0)