Repository navigation
v0.36.0 — performance
Performance release.
Client: fan-out connections open when they get work
Client.scalar_function and table_in_out_function opened every connection max_workers allowed before sending the first batch. Scalar and table-in-out functions default to unlimited max_workers, so the client capped it at the CPU count: one call on one batch opened 48 connections on a 48-core machine — 47 idle worker processes on the subprocess transport. A secondary connection now opens when the first batch is dealt to it (batch i still goes to connection i % max_workers), so n batches use min(n, max_workers) connections. A trivial call went from 0.4–1 s to ~10 ms. table_function is unchanged (no input to deal).
Dynamic filters over HTTP: no more quadratic replay
HTTP table streams carried every dynamic-filter delta ever received in their per-turn state and replayed all of them — re-validating each predicate through the embedded DuckDB — on every turn, so turn k did k validations. The state now keeps only the deltas that set a predicate's current revision, and a turn rebuilt from state the worker sealed itself skips the re-check. With the matching extension change (it now sends a delta only when a filter changes), dynamic_filter.test went from ~205 s to ~8 s and sequence.test from ~109 s to ~8 s. The embedded filter evaluator runs single-threaded (it was a 48-thread pool per server thread).
Catalog listings built once
Every function listing rebuilt and Arrow-encoded a FunctionInfo for all of a worker's functions (≈134 ms of worker time per call for the example worker's 162 table functions). Each (schema, type) listing is now built once per worker and each item encoded once: a warm listing costs ≈0.3 ms. DuckDB makes this call when it loads a function set.
Smaller
vgi.authloads its HTTP/JWT helpers on first use:import vgi0.89 s → 0.56 s.vgi.auth.__all__no longer lists them — import them by name, as before.- Test fixtures: partitioned fixtures declare
max_workersequal to their work items; the suite runs with one OpenBLAS thread per process and xdistworksteal.
The vgi-python suite: 66–69 s → 15–27 s on 48 cores.