Skip to content

Commit 5b7ea6d

Browse files
Iteration 158: 5 new benchmark pairs (508 total, +5 vs best 503)
Run: https://github.com/githubnext/tsessebe/actions/runs/24573945763
1 parent ba235be commit 5b7ea6d

10 files changed

Lines changed: 424 additions & 0 deletions
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Benchmark: pandas DataFrame.median() — column-wise median on a 100k-row DataFrame.
3+
Outputs JSON: {"function": "dataframe_median", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import pandas as pd
8+
import numpy as np
9+
10+
SIZE = 100_000
11+
WARMUP = 5
12+
ITERATIONS = 30
13+
14+
df = pd.DataFrame({
15+
"a": (np.arange(SIZE) * 1.23) % 9000,
16+
"b": (np.arange(SIZE) * 4.56) % 7000,
17+
"c": (np.arange(SIZE) * 7.89) % 5000,
18+
})
19+
20+
for _ in range(WARMUP):
21+
df.median()
22+
23+
times = []
24+
for _ in range(ITERATIONS):
25+
t0 = time.perf_counter()
26+
df.median()
27+
times.append((time.perf_counter() - t0) * 1000)
28+
29+
total_ms = sum(times)
30+
mean_ms = total_ms / ITERATIONS
31+
print(json.dumps({
32+
"function": "dataframe_median",
33+
"mean_ms": mean_ms,
34+
"iterations": ITERATIONS,
35+
"total_ms": total_ms,
36+
}))
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""
2+
Benchmark: pandas DataFrame.rolling().min() / .max() — rolling min/max aggregations.
3+
Outputs JSON: {"function": "dataframe_rolling_min_max", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import pandas as pd
8+
import numpy as np
9+
10+
SIZE = 50_000
11+
WINDOW = 20
12+
WARMUP = 5
13+
ITERATIONS = 30
14+
15+
df = pd.DataFrame({
16+
"a": np.sin(np.arange(SIZE) * 0.01) * 100,
17+
"b": np.cos(np.arange(SIZE) * 0.01) * 50,
18+
"c": (np.arange(SIZE) % 100) * 1.5,
19+
})
20+
21+
for _ in range(WARMUP):
22+
df.rolling(WINDOW).min()
23+
df.rolling(WINDOW).max()
24+
25+
times = []
26+
for _ in range(ITERATIONS):
27+
t0 = time.perf_counter()
28+
df.rolling(WINDOW).min()
29+
df.rolling(WINDOW).max()
30+
times.append((time.perf_counter() - t0) * 1000)
31+
32+
total_ms = sum(times)
33+
mean_ms = total_ms / ITERATIONS
34+
print(json.dumps({
35+
"function": "dataframe_rolling_min_max",
36+
"mean_ms": mean_ms,
37+
"iterations": ITERATIONS,
38+
"total_ms": total_ms,
39+
}))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
Benchmark: pandas IntervalIndex.from_arrays() and IntervalIndex.from_tuples() — alternative constructors.
3+
Outputs JSON: {"function": "interval_index_construction", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import pandas as pd
8+
import numpy as np
9+
10+
SIZE = 10_000
11+
WARMUP = 5
12+
ITERATIONS = 50
13+
14+
# Prepare data
15+
left_arr = np.arange(SIZE) * 0.1
16+
right_arr = left_arr + 0.1
17+
18+
# Prepare tuples for from_tuples
19+
tuples = [(left_arr[i], right_arr[i]) for i in range(SIZE)]
20+
21+
for _ in range(WARMUP):
22+
pd.IntervalIndex.from_arrays(left_arr, right_arr)
23+
pd.IntervalIndex.from_arrays(left_arr, right_arr, closed="left")
24+
pd.IntervalIndex.from_tuples(tuples)
25+
26+
times = []
27+
for _ in range(ITERATIONS):
28+
t0 = time.perf_counter()
29+
pd.IntervalIndex.from_arrays(left_arr, right_arr)
30+
pd.IntervalIndex.from_arrays(left_arr, right_arr, closed="left")
31+
pd.IntervalIndex.from_tuples(tuples)
32+
times.append((time.perf_counter() - t0) * 1000)
33+
34+
total_ms = sum(times)
35+
mean_ms = total_ms / ITERATIONS
36+
print(json.dumps({
37+
"function": "interval_index_construction",
38+
"mean_ms": mean_ms,
39+
"iterations": ITERATIONS,
40+
"total_ms": total_ms,
41+
}))
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
Benchmark: pandas read_csv with options — sep, header, skiprows, dtype casting.
3+
Outputs JSON: {"function": "read_csv_options", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import io
7+
import time
8+
import pandas as pd
9+
import numpy as np
10+
11+
ROWS = 10_000
12+
WARMUP = 3
13+
ITERATIONS = 20
14+
15+
# Build pipe-separated CSV (no header)
16+
pipe_lines = [f"{i}|{i * 1.1:.4f}|cat_{i % 50}" for i in range(ROWS)]
17+
pipe_csv = "\n".join(pipe_lines)
18+
19+
# Build comma-separated CSV (skip first 2 rows)
20+
skip_lines = ["# comment row 1", "# comment row 2", "id,value,label"] + \
21+
[f"{i},{i * 2.2:.4f},grp_{i % 20}" for i in range(ROWS)]
22+
skip_csv = "\n".join(skip_lines)
23+
24+
# Build CSV for dtype override
25+
dtype_lines = ["id,value,flag"] + [f"{i},{i * 1.5},{i % 2}" for i in range(ROWS)]
26+
dtype_csv = "\n".join(dtype_lines)
27+
28+
for _ in range(WARMUP):
29+
pd.read_csv(io.StringIO(pipe_csv), sep="|", header=None)
30+
pd.read_csv(io.StringIO(skip_csv), skiprows=2)
31+
pd.read_csv(io.StringIO(dtype_csv), dtype={"id": "int32", "value": "float32"})
32+
33+
times = []
34+
for _ in range(ITERATIONS):
35+
t0 = time.perf_counter()
36+
pd.read_csv(io.StringIO(pipe_csv), sep="|", header=None)
37+
pd.read_csv(io.StringIO(skip_csv), skiprows=2)
38+
pd.read_csv(io.StringIO(dtype_csv), dtype={"id": "int32", "value": "float32"})
39+
times.append((time.perf_counter() - t0) * 1000)
40+
41+
total_ms = sum(times)
42+
mean_ms = total_ms / ITERATIONS
43+
print(json.dumps({
44+
"function": "read_csv_options",
45+
"mean_ms": mean_ms,
46+
"iterations": ITERATIONS,
47+
"total_ms": total_ms,
48+
}))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
Benchmark: pandas DataFrame.to_csv() with options — sep, header, index settings.
3+
Outputs JSON: {"function": "to_csv_options", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
"""
5+
import json
6+
import time
7+
import pandas as pd
8+
import numpy as np
9+
10+
ROWS = 10_000
11+
WARMUP = 3
12+
ITERATIONS = 20
13+
14+
df = pd.DataFrame({
15+
"id": np.arange(ROWS),
16+
"value": np.arange(ROWS) * 1.1,
17+
"label": [f"cat_{i % 50}" for i in range(ROWS)],
18+
})
19+
20+
for _ in range(WARMUP):
21+
df.to_csv(sep="\t")
22+
df.to_csv(header=False)
23+
df.to_csv(index=False)
24+
df.to_csv(sep="|", header=False, index=False)
25+
26+
times = []
27+
for _ in range(ITERATIONS):
28+
t0 = time.perf_counter()
29+
df.to_csv(sep="\t")
30+
df.to_csv(header=False)
31+
df.to_csv(index=False)
32+
df.to_csv(sep="|", header=False, index=False)
33+
times.append((time.perf_counter() - t0) * 1000)
34+
35+
total_ms = sum(times)
36+
mean_ms = total_ms / ITERATIONS
37+
print(json.dumps({
38+
"function": "to_csv_options",
39+
"mean_ms": mean_ms,
40+
"iterations": ITERATIONS,
41+
"total_ms": total_ms,
42+
}))
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Benchmark: DataFrame.median() — column-wise median on a 100k-row DataFrame.
3+
* Outputs JSON: {"function": "dataframe_median", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame } from "../../src/index.ts";
6+
7+
const SIZE = 100_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 30;
10+
11+
const df = DataFrame.fromColumns({
12+
a: Array.from({ length: SIZE }, (_, i) => (i * 1.23) % 9000),
13+
b: Array.from({ length: SIZE }, (_, i) => (i * 4.56) % 7000),
14+
c: Array.from({ length: SIZE }, (_, i) => (i * 7.89) % 5000),
15+
});
16+
17+
for (let i = 0; i < WARMUP; i++) {
18+
df.median();
19+
}
20+
21+
const times: number[] = [];
22+
for (let i = 0; i < ITERATIONS; i++) {
23+
const t0 = performance.now();
24+
df.median();
25+
times.push(performance.now() - t0);
26+
}
27+
28+
const totalMs = times.reduce((a, b) => a + b, 0);
29+
const meanMs = totalMs / ITERATIONS;
30+
console.log(
31+
JSON.stringify({
32+
function: "dataframe_median",
33+
mean_ms: meanMs,
34+
iterations: ITERATIONS,
35+
total_ms: totalMs,
36+
}),
37+
);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Benchmark: DataFrameRolling.min() and DataFrameRolling.max() on a 50k-row DataFrame.
3+
* Outputs JSON: {"function": "dataframe_rolling_min_max", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { DataFrame } from "../../src/index.ts";
6+
7+
const SIZE = 50_000;
8+
const WINDOW = 20;
9+
const WARMUP = 5;
10+
const ITERATIONS = 30;
11+
12+
const df = DataFrame.fromColumns({
13+
a: Array.from({ length: SIZE }, (_, i) => Math.sin(i * 0.01) * 100),
14+
b: Array.from({ length: SIZE }, (_, i) => Math.cos(i * 0.01) * 50),
15+
c: Array.from({ length: SIZE }, (_, i) => (i % 100) * 1.5),
16+
});
17+
18+
for (let i = 0; i < WARMUP; i++) {
19+
df.rolling(WINDOW).min();
20+
df.rolling(WINDOW).max();
21+
}
22+
23+
const times: number[] = [];
24+
for (let i = 0; i < ITERATIONS; i++) {
25+
const t0 = performance.now();
26+
df.rolling(WINDOW).min();
27+
df.rolling(WINDOW).max();
28+
times.push(performance.now() - t0);
29+
}
30+
31+
const totalMs = times.reduce((a, b) => a + b, 0);
32+
const meanMs = totalMs / ITERATIONS;
33+
console.log(
34+
JSON.stringify({
35+
function: "dataframe_rolling_min_max",
36+
mean_ms: meanMs,
37+
iterations: ITERATIONS,
38+
total_ms: totalMs,
39+
}),
40+
);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Benchmark: IntervalIndex.fromArrays() and IntervalIndex.fromIntervals() — alternative constructors.
3+
* Outputs JSON: {"function": "interval_index_construction", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { Interval, IntervalIndex } from "../../src/index.ts";
6+
7+
const SIZE = 10_000;
8+
const WARMUP = 5;
9+
const ITERATIONS = 50;
10+
11+
// Prepare data for fromArrays
12+
const leftArr = Array.from({ length: SIZE }, (_, i) => i * 0.1);
13+
const rightArr = Array.from({ length: SIZE }, (_, i) => i * 0.1 + 0.1);
14+
15+
// Prepare interval objects for fromIntervals
16+
const intervals = Array.from({ length: SIZE }, (_, i) => new Interval(i * 0.1, i * 0.1 + 0.1));
17+
18+
for (let i = 0; i < WARMUP; i++) {
19+
IntervalIndex.fromArrays(leftArr, rightArr);
20+
IntervalIndex.fromArrays(leftArr, rightArr, "left");
21+
IntervalIndex.fromIntervals(intervals);
22+
}
23+
24+
const times: number[] = [];
25+
for (let i = 0; i < ITERATIONS; i++) {
26+
const t0 = performance.now();
27+
IntervalIndex.fromArrays(leftArr, rightArr);
28+
IntervalIndex.fromArrays(leftArr, rightArr, "left");
29+
IntervalIndex.fromIntervals(intervals);
30+
times.push(performance.now() - t0);
31+
}
32+
33+
const totalMs = times.reduce((a, b) => a + b, 0);
34+
const meanMs = totalMs / ITERATIONS;
35+
console.log(
36+
JSON.stringify({
37+
function: "interval_index_construction",
38+
mean_ms: meanMs,
39+
iterations: ITERATIONS,
40+
total_ms: totalMs,
41+
}),
42+
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Benchmark: readCsv with options — sep, header, skipRows, dtype casting.
3+
* Outputs JSON: {"function": "read_csv_options", "mean_ms": ..., "iterations": ..., "total_ms": ...}
4+
*/
5+
import { readCsv } from "../../src/index.ts";
6+
7+
const ROWS = 10_000;
8+
const WARMUP = 3;
9+
const ITERATIONS = 20;
10+
11+
// Build pipe-separated CSV (no header)
12+
const pipeLines: string[] = [];
13+
for (let i = 0; i < ROWS; i++) {
14+
pipeLines.push(`${i}|${(i * 1.1).toFixed(4)}|cat_${i % 50}`);
15+
}
16+
const pipeCsv = pipeLines.join("\n");
17+
18+
// Build comma-separated CSV (skip first 2 rows)
19+
const skipLines: string[] = ["# comment row 1", "# comment row 2", "id,value,label"];
20+
for (let i = 0; i < ROWS; i++) {
21+
skipLines.push(`${i},${(i * 2.2).toFixed(4)},grp_${i % 20}`);
22+
}
23+
const skipCsv = skipLines.join("\n");
24+
25+
// Build CSV for dtype override
26+
const dtypeLines: string[] = ["id,value,flag"];
27+
for (let i = 0; i < ROWS; i++) {
28+
dtypeLines.push(`${i},${i * 1.5},${i % 2}`);
29+
}
30+
const dtypeCsv = dtypeLines.join("\n");
31+
32+
for (let i = 0; i < WARMUP; i++) {
33+
readCsv(pipeCsv, { sep: "|", header: null });
34+
readCsv(skipCsv, { skipRows: 2 });
35+
readCsv(dtypeCsv, { dtype: { id: "int32", value: "float32" } });
36+
}
37+
38+
const times: number[] = [];
39+
for (let i = 0; i < ITERATIONS; i++) {
40+
const t0 = performance.now();
41+
readCsv(pipeCsv, { sep: "|", header: null });
42+
readCsv(skipCsv, { skipRows: 2 });
43+
readCsv(dtypeCsv, { dtype: { id: "int32", value: "float32" } });
44+
times.push(performance.now() - t0);
45+
}
46+
47+
const totalMs = times.reduce((a, b) => a + b, 0);
48+
const meanMs = totalMs / ITERATIONS;
49+
console.log(
50+
JSON.stringify({
51+
function: "read_csv_options",
52+
mean_ms: meanMs,
53+
iterations: ITERATIONS,
54+
total_ms: totalMs,
55+
}),
56+
);

0 commit comments

Comments
 (0)