Skip to content

Run aggregate and group-by computes on the local engine - #89

Merged
clojure-finance merged 1 commit into
2.x.xfrom
local-engine-aggregate
Oct 13, 2026
Merged

clojure-finance merged 1 commit into
2.x.xfrom
local-engine-aggregate

Conversation

@buehlmaier

Copy link
Copy Markdown
Collaborator

Stage 2 of replacing Onyx (stage 1 was #88). With clojask.engine=local (or CLOJASK_ENGINE=local), aggregate-only, group-by and group-aggregate computes no longer start Onyx. The default engine is still Onyx.

  • engine/start-aggre-only folds the rows in input order on the calling thread and writes the result.
  • engine/start-groupby writes the rows to their group files or to the in-memory groups.
  • engine/start-aggre aggregates one group per pool task.

They take the same arguments as the Onyx drivers they replace; DataFrame.computeAggre and computeGroupAggre pick one by the flag. Joins, including their group-by phase, still run on Onyx (stage 3).

Tests

New engine-test runs each of these computes on both engines and compares the sorted output, with Onyx made unreachable during the local run: aggregate-only, group-aggregate on disk and in memory, a multi-row aggregate with :select, group-by only, and a failing aggregate (staged ExecutionException on both engines, no group files left). Written first; before the port only the local runs failed.

lein test: 57 tests / 216 assertions green with CLOJASK_ENGINE=local and with the default engine (JDK 25).

Benchmark

Synthetic 1.8M-row, 160 MB Compustat-like CSV, JDK 25, 8 cores, seconds, Onyx → local:

Workers Aggregate-only Group-aggregate on disk Group-aggregate in memory
1 6.0 → 3.1 57 → 48 15.9 → 7.6
4 6.4 → 3.4 61 → 46 16.7 → 5.6
8 6.4 → 4.4 59 → 44 18.4 → 5.4

Group-aggregate on disk is dominated on both engines by opening the group file once per row.

Output is identical except for the last digits of group means (max relative difference 4e-15): Onyx feeds a group's rows in arbitrary order, so its disk and in-memory runs differ from each other; the local engine adds them in input order and its two runs match exactly.

With clojask.engine=local, aggregate-only, group-by and group-aggregate
computes no longer start Onyx. engine/start-aggre-only folds the rows
in input order on the calling thread, engine/start-groupby writes the
rows to their group files or the in-memory groups, and
engine/start-aggre aggregates one group per pool task. They take the
same arguments as the Onyx drivers they replace. Joins still run on
Onyx, including their group-by phase.

engine-test runs each of these computes on both engines and compares
the sorted output, with Onyx made unreachable during the local run. It
also checks that a failing aggregate surfaces as an ExecutionException
on both engines and leaves no group files.
@clojure-finance
clojure-finance merged commit 5f80de0 into 2.x.x Oct 13, 2026
3 checks passed
@buehlmaier
buehlmaier deleted the local-engine-aggregate branch October 13, 2026 09:02
This was referenced Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants