Skip to content

Commit a770db3

Browse files
Iteration 165: 5 new benchmark pairs (513 total, +5 vs branch 508)
Added benchmark pairs for: - series_set_reset_index: Series.setIndex() and Series.resetIndex() - melt_id_vars: melt() with id_vars, var_name, value_name options - concat_series_axis0: concat of 5 Series along axis=0 - stack_options: stack() with dropna=true/false options - sample_frac: sampleSeries/sampleDataFrame with frac option Run: https://github.com/githubnext/tsessebe/actions/runs/24585962377 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 94a76b2 commit a770db3

10 files changed

Lines changed: 368 additions & 0 deletions
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Benchmark: pd.concat of multiple Series along axis=0 — vertical stacking
2+
of 5 Series of 20k elements each."""
3+
import json, time
4+
import numpy as np
5+
import pandas as pd
6+
7+
CHUNK = 20_000
8+
WARMUP = 5
9+
ITERATIONS = 30
10+
11+
s1 = pd.Series(np.arange(CHUNK, dtype=float) * 1.0)
12+
s2 = pd.Series(np.arange(CHUNK, dtype=float) * 2.0)
13+
s3 = pd.Series(np.arange(CHUNK, dtype=float) * 3.0)
14+
s4 = pd.Series(np.arange(CHUNK, dtype=float) * 4.0)
15+
s5 = pd.Series(np.arange(CHUNK, dtype=float) * 5.0)
16+
17+
for _ in range(WARMUP):
18+
pd.concat([s1, s2, s3, s4, s5])
19+
20+
start = time.perf_counter()
21+
for _ in range(ITERATIONS):
22+
pd.concat([s1, s2, s3, s4, s5])
23+
total = (time.perf_counter() - start) * 1000
24+
25+
print(json.dumps({
26+
"function": "concat_series_axis0",
27+
"mean_ms": total / ITERATIONS,
28+
"iterations": ITERATIONS,
29+
"total_ms": total,
30+
}))
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Benchmark: pd.melt with id_vars — unpivot keeping identifier columns fixed,
2+
with custom var_name and value_name on a 10k-row DataFrame."""
3+
import json, time
4+
import numpy as np
5+
import pandas as pd
6+
7+
ROWS = 10_000
8+
WARMUP = 5
9+
ITERATIONS = 30
10+
11+
ids = [f"id_{i}" for i in range(ROWS)]
12+
category = ["A", "B", "C"][ : ROWS]
13+
category = [["A", "B", "C"][i % 3] for i in range(ROWS)]
14+
q1 = np.arange(ROWS, dtype=float)
15+
q2 = np.arange(ROWS, dtype=float) * 1.1
16+
q3 = np.arange(ROWS, dtype=float) * 1.2
17+
q4 = np.arange(ROWS, dtype=float) * 1.3
18+
19+
df = pd.DataFrame({"id": ids, "category": category, "Q1": q1, "Q2": q2, "Q3": q3, "Q4": q4})
20+
21+
for _ in range(WARMUP):
22+
pd.melt(df, id_vars=["id", "category"], var_name="quarter", value_name="revenue")
23+
24+
start = time.perf_counter()
25+
for _ in range(ITERATIONS):
26+
pd.melt(df, id_vars=["id", "category"], var_name="quarter", value_name="revenue")
27+
total = (time.perf_counter() - start) * 1000
28+
29+
print(json.dumps({
30+
"function": "melt_id_vars",
31+
"mean_ms": total / ITERATIONS,
32+
"iterations": ITERATIONS,
33+
"total_ms": total,
34+
}))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Benchmark: Series.sample(frac=...) and DataFrame.sample(frac=...) —
2+
fractional sampling (10% of 100k elements) with and without replacement."""
3+
import json, time
4+
import numpy as np
5+
import pandas as pd
6+
7+
ROWS = 100_000
8+
WARMUP = 3
9+
ITERATIONS = 20
10+
11+
data = np.arange(ROWS, dtype=float) * 1.5
12+
s = pd.Series(data)
13+
df = pd.DataFrame({
14+
"a": np.arange(ROWS, dtype=float),
15+
"b": np.arange(ROWS, dtype=float) * 2.0,
16+
"c": np.arange(ROWS, dtype=float) * 3.0,
17+
})
18+
19+
for _ in range(WARMUP):
20+
s.sample(frac=0.1)
21+
s.sample(frac=0.05, replace=True)
22+
df.sample(frac=0.1)
23+
24+
start = time.perf_counter()
25+
for _ in range(ITERATIONS):
26+
s.sample(frac=0.1)
27+
s.sample(frac=0.05, replace=True)
28+
df.sample(frac=0.1)
29+
total = (time.perf_counter() - start) * 1000
30+
31+
print(json.dumps({
32+
"function": "sample_frac",
33+
"mean_ms": total / ITERATIONS,
34+
"iterations": ITERATIONS,
35+
"total_ms": total,
36+
}))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Benchmark: Series.set_axis() and Series.reset_index() — reassign or reset the
2+
row-index of a 100k-element Series."""
3+
import json, time
4+
import numpy as np
5+
import pandas as pd
6+
7+
SIZE = 100_000
8+
WARMUP = 5
9+
ITERATIONS = 50
10+
11+
data = np.arange(SIZE, dtype=float) * 1.5
12+
s = pd.Series(data)
13+
new_index = pd.Index(np.arange(SIZE) * 2)
14+
15+
for _ in range(WARMUP):
16+
s.set_axis(new_index)
17+
s.reset_index(drop=True)
18+
19+
start = time.perf_counter()
20+
for _ in range(ITERATIONS):
21+
s.set_axis(new_index)
22+
s.reset_index(drop=True)
23+
total = (time.perf_counter() - start) * 1000
24+
25+
print(json.dumps({
26+
"function": "series_set_reset_index",
27+
"mean_ms": total / ITERATIONS,
28+
"iterations": ITERATIONS,
29+
"total_ms": total,
30+
}))
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""Benchmark: DataFrame.stack with dropna=True/False options — includes null values
2+
in the output on a 2k-row x 5-column DataFrame."""
3+
import json, time
4+
import numpy as np
5+
import pandas as pd
6+
7+
ROWS = 2_000
8+
WARMUP = 5
9+
ITERATIONS = 30
10+
11+
def make_col(mul: float) -> list:
12+
return [None if i % 10 == 0 else float(i) * mul for i in range(ROWS)]
13+
14+
df = pd.DataFrame({
15+
"a": make_col(1.0),
16+
"b": make_col(1.1),
17+
"c": make_col(1.2),
18+
"d": make_col(1.3),
19+
"e": make_col(1.4),
20+
})
21+
22+
for _ in range(WARMUP):
23+
df.stack(dropna=True)
24+
df.stack(dropna=False)
25+
26+
start = time.perf_counter()
27+
for _ in range(ITERATIONS):
28+
df.stack(dropna=True)
29+
df.stack(dropna=False)
30+
total = (time.perf_counter() - start) * 1000
31+
32+
print(json.dumps({
33+
"function": "stack_options",
34+
"mean_ms": total / ITERATIONS,
35+
"iterations": ITERATIONS,
36+
"total_ms": total,
37+
}))
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Benchmark: concat of multiple Series objects along axis=0 — vertical stacking
3+
* of 5 Series of 20k elements each.
4+
* Outputs JSON: {"function": "concat_series_axis0", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { Series, concat } from "../../src/index.ts";
7+
8+
const CHUNK = 20_000;
9+
const WARMUP = 5;
10+
const ITERATIONS = 30;
11+
12+
const s1 = new Series({ data: Array.from({ length: CHUNK }, (_, i) => i * 1.0) });
13+
const s2 = new Series({ data: Array.from({ length: CHUNK }, (_, i) => i * 2.0) });
14+
const s3 = new Series({ data: Array.from({ length: CHUNK }, (_, i) => i * 3.0) });
15+
const s4 = new Series({ data: Array.from({ length: CHUNK }, (_, i) => i * 4.0) });
16+
const s5 = new Series({ data: Array.from({ length: CHUNK }, (_, i) => i * 5.0) });
17+
18+
for (let i = 0; i < WARMUP; i++) {
19+
concat([s1, s2, s3, s4, s5]);
20+
}
21+
22+
const start = performance.now();
23+
for (let i = 0; i < ITERATIONS; i++) {
24+
concat([s1, s2, s3, s4, s5]);
25+
}
26+
const total = performance.now() - start;
27+
28+
console.log(
29+
JSON.stringify({
30+
function: "concat_series_axis0",
31+
mean_ms: total / ITERATIONS,
32+
iterations: ITERATIONS,
33+
total_ms: total,
34+
}),
35+
);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Benchmark: melt with id_vars — unpivot a wide DataFrame keeping identifier
3+
* columns fixed, with custom var_name and value_name on a 10k-row DataFrame.
4+
* Outputs JSON: {"function": "melt_id_vars", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { DataFrame, melt } from "../../src/index.ts";
7+
8+
const ROWS = 10_000;
9+
const WARMUP = 5;
10+
const ITERATIONS = 30;
11+
12+
const ids = Array.from({ length: ROWS }, (_, i) => `id_${i}`);
13+
const category = Array.from({ length: ROWS }, (_, i) => ["A", "B", "C"][i % 3]);
14+
const q1 = Array.from({ length: ROWS }, (_, i) => i * 1.0);
15+
const q2 = Array.from({ length: ROWS }, (_, i) => i * 1.1);
16+
const q3 = Array.from({ length: ROWS }, (_, i) => i * 1.2);
17+
const q4 = Array.from({ length: ROWS }, (_, i) => i * 1.3);
18+
19+
const df = DataFrame.fromColumns({ id: ids, category, Q1: q1, Q2: q2, Q3: q3, Q4: q4 });
20+
21+
for (let i = 0; i < WARMUP; i++) {
22+
melt(df, {
23+
id_vars: ["id", "category"],
24+
var_name: "quarter",
25+
value_name: "revenue",
26+
});
27+
}
28+
29+
const start = performance.now();
30+
for (let i = 0; i < ITERATIONS; i++) {
31+
melt(df, {
32+
id_vars: ["id", "category"],
33+
var_name: "quarter",
34+
value_name: "revenue",
35+
});
36+
}
37+
const total = performance.now() - start;
38+
39+
console.log(
40+
JSON.stringify({
41+
function: "melt_id_vars",
42+
mean_ms: total / ITERATIONS,
43+
iterations: ITERATIONS,
44+
total_ms: total,
45+
}),
46+
);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Benchmark: sampleSeries with frac option and sampleDataFrame with frac option.
3+
* Fractional sampling (10% of 100k elements) with and without replacement.
4+
* Outputs JSON: {"function": "sample_frac", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { Series, DataFrame, sampleSeries, sampleDataFrame } from "../../src/index.ts";
7+
8+
const ROWS = 100_000;
9+
const WARMUP = 3;
10+
const ITERATIONS = 20;
11+
12+
const data = Array.from({ length: ROWS }, (_, i) => i * 1.5);
13+
const s = new Series({ data });
14+
15+
const df = DataFrame.fromColumns({
16+
a: Array.from({ length: ROWS }, (_, i) => i * 1.0),
17+
b: Array.from({ length: ROWS }, (_, i) => i * 2.0),
18+
c: Array.from({ length: ROWS }, (_, i) => i * 3.0),
19+
});
20+
21+
for (let i = 0; i < WARMUP; i++) {
22+
sampleSeries(s, { frac: 0.1 });
23+
sampleSeries(s, { frac: 0.05, replace: true });
24+
sampleDataFrame(df, { frac: 0.1 });
25+
}
26+
27+
const start = performance.now();
28+
for (let i = 0; i < ITERATIONS; i++) {
29+
sampleSeries(s, { frac: 0.1 });
30+
sampleSeries(s, { frac: 0.05, replace: true });
31+
sampleDataFrame(df, { frac: 0.1 });
32+
}
33+
const total = performance.now() - start;
34+
35+
console.log(
36+
JSON.stringify({
37+
function: "sample_frac",
38+
mean_ms: total / ITERATIONS,
39+
iterations: ITERATIONS,
40+
total_ms: total,
41+
}),
42+
);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Benchmark: Series.setIndex() and Series.resetIndex() — reassign or reset the
3+
* row-index of a 100k-element Series.
4+
* Outputs JSON: {"function": "series_set_reset_index", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { Index, Series } from "../../src/index.ts";
7+
8+
const SIZE = 100_000;
9+
const WARMUP = 5;
10+
const ITERATIONS = 50;
11+
12+
const data = Array.from({ length: SIZE }, (_, i) => i * 1.5);
13+
const s = new Series({ data });
14+
const newIndex = new Index<number>(Array.from({ length: SIZE }, (_, i) => i * 2));
15+
16+
for (let i = 0; i < WARMUP; i++) {
17+
s.setIndex(newIndex);
18+
s.resetIndex();
19+
}
20+
21+
const start = performance.now();
22+
for (let i = 0; i < ITERATIONS; i++) {
23+
s.setIndex(newIndex);
24+
s.resetIndex();
25+
}
26+
const total = performance.now() - start;
27+
28+
console.log(
29+
JSON.stringify({
30+
function: "series_set_reset_index",
31+
mean_ms: total / ITERATIONS,
32+
iterations: ITERATIONS,
33+
total_ms: total,
34+
}),
35+
);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Benchmark: stack with dropna=false option — includes null values in the output
3+
* on a 2k-row x 5-column DataFrame (100k total cells including nulls).
4+
* Outputs JSON: {"function": "stack_options", "mean_ms": ..., "iterations": ..., "total_ms": ...}
5+
*/
6+
import { DataFrame, stack } from "../../src/index.ts";
7+
8+
const ROWS = 2_000;
9+
const WARMUP = 5;
10+
const ITERATIONS = 30;
11+
12+
// Create a DataFrame with some null values (every 10th element is null)
13+
const makeCol = (mul: number) =>
14+
Array.from({ length: ROWS }, (_, i) => (i % 10 === 0 ? null : i * mul));
15+
16+
const df = DataFrame.fromColumns({
17+
a: makeCol(1.0),
18+
b: makeCol(1.1),
19+
c: makeCol(1.2),
20+
d: makeCol(1.3),
21+
e: makeCol(1.4),
22+
});
23+
24+
for (let i = 0; i < WARMUP; i++) {
25+
stack(df, { dropna: true });
26+
stack(df, { dropna: false });
27+
}
28+
29+
const start = performance.now();
30+
for (let i = 0; i < ITERATIONS; i++) {
31+
stack(df, { dropna: true });
32+
stack(df, { dropna: false });
33+
}
34+
const total = performance.now() - start;
35+
36+
console.log(
37+
JSON.stringify({
38+
function: "stack_options",
39+
mean_ms: total / ITERATIONS,
40+
iterations: ITERATIONS,
41+
total_ms: total,
42+
}),
43+
);

0 commit comments

Comments
 (0)