Skip to content

Commit 74e989e

Browse files
rustyconoverclaude
andcommitted
test fixtures: build cache_parallel batches with one vectorised add
Each batch was a Python list of ints, about 1 µs a row; the spill-stream guard emits tens of millions of rows. Add the batch start to a cached 0..n-1 int64 array instead. Output is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent a34e949 commit 74e989e

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

‎vgi/_test_fixtures/table/cache.py‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from typing import Annotated, Any, ClassVar, cast
3131

3232
import pyarrow as pa
33+
import pyarrow.compute as pc
3334
from vgi_rpc import ArrowSerializableDataclass
3435
from vgi_rpc.rpc import OutputCollector
3536

@@ -945,7 +946,7 @@ def process(
945946
# sequence [0..rows) so COUNT=rows and SUM=rows*(rows-1)/2 regardless of how the
946947
# chunks were distributed across workers. Positional Arg(0) so the direct path
947948
# `vgi_table_function(w, 'cache_parallel', [rows])` honors the size; a named
948-
# `batch_size` (default 24000) controls batch width for the 2 GB streaming guard.
949+
# `batch_size` (default 24000) controls batch width for the disk-streaming guard (parallel_2gb.test_slow).
949950
_PC_ITEM_FMT = ">QQ" # (start, end) as two uint64
950951
_PC_ITEM_SIZE = struct.calcsize(_PC_ITEM_FMT)
951952

@@ -1001,6 +1002,16 @@ class Meta:
10011002

10021003
FunctionArguments = CacheParallelArgs
10031004

1005+
_OFFSETS: ClassVar[dict[int, pa.Int64Array]] = {}
1006+
1007+
@classmethod
1008+
def _offsets(cls, n: int) -> pa.Int64Array:
1009+
"""0 .. n-1 as int64, built once per batch size per process."""
1010+
arr = cls._OFFSETS.get(n)
1011+
if arr is None:
1012+
arr = cls._OFFSETS[n] = pa.array(range(n), type=pa.int64())
1013+
return arr
1014+
10041015
@classmethod
10051016
def on_init(cls, params: InitParams[CacheParallelArgs]) -> GlobalInitResponse:
10061017
"""Primary worker enqueues (start, end) chunks covering [0, rows)."""
@@ -1032,8 +1043,11 @@ def process(
10321043
state.current_idx = state.current_start
10331044

10341045
batch_end = min(state.current_idx + params.args.batch_size, state.current_end or 0)
1035-
values = list(range(state.current_idx, batch_end))
1036-
batch = pa.RecordBatch.from_pydict({"v": values}, schema=params.output_schema)
1046+
# v = current_idx .. batch_end-1, as one vectorised add to a cached 0..n-1
1047+
# (a Python list costs ~1 µs a row, which the 640 MB streaming guard pays 80M times).
1048+
base = cls._offsets(params.args.batch_size).slice(0, batch_end - state.current_idx)
1049+
values = pc.add(base, pa.scalar(state.current_idx, type=pa.int64()))
1050+
batch = pa.RecordBatch.from_arrays([values], schema=params.output_schema)
10371051
cache_control = CacheControl(ttl=_DEFAULT_TTL_SECONDS) if not state.advertised else None
10381052
cast(VgiOutputCollector, out).emit(batch, cache_control=cache_control)
10391053
state.advertised = True

0 commit comments

Comments
 (0)