Skip to content

New helpers - #237

Merged
hovsep merged 4 commits into
mainfrom
new_helpers
Jul 30, 2026
Merged

New helpers#237
hovsep merged 4 commits into
mainfrom
new_helpers

Conversation

@hovsep

@hovsep hovsep commented Jul 30, 2026

Copy link
Copy Markdown
Owner

This pull request introduces several improvements and new features to the component activation and data flow system, as well as updates to the documentation and tests. The main focus is on providing a set of composable activation function combinators (Sequential, When, RequireInputs, Pipeline) in component/compose.go, clarifying the behavior of port name resolution, and updating documentation and examples to use safer, more ergonomic signal payload accessors. Tests are added to ensure correct behavior, and documentation is expanded to clarify design constraints and best practices.

New Activation Function Combinators and Port Name Handling:

  • Added component/compose.go with composable activation function combinators: Sequential, When, HasSignalsOn, RequireInputs, and Pipeline, enabling flexible and safe composition of component logic. These combinators handle port existence checks, error propagation, and input ordering, and provide clear error messages for missing ports.
  • Updated documentation to clarify that helpers taking port names as strings must resolve every name before operating, and must report unresolved names instead of silently skipping or waiting forever. This prevents subtle bugs from misspelled port names.

Documentation and Example Improvements:

  • Expanded documentation in .agent/docs/design.md and .agent/docs/naming.md to describe the new combinators, the rationale for short, constraint-focused comments, and the importance of explicit error handling for unresolved port names and signal payload types. [1] [2]
  • Updated the README.md and quick-start wiki to use signal.AsOrDefault and signal.AsInt, replacing unsafe type assertions with error-checked or default-returning accessors. This makes example code safer and more idiomatic. [1] [2] [3] [4]

Testing Enhancements:

  • Added comprehensive tests in component/compose_test.go covering all new combinators, including edge cases such as missing ports, nil groups, and error propagation. Tests ensure that combinators behave as documented and fail safely on invalid input.
  • Updated testing guidelines to require coverage for unresolved port names and typed payload accessors, ensuring that these cases are never missed in future tests. [1] [2]

Other Notable Updates:

  • Minor docstring addition in component/doc.go referencing the new combinators for discoverability.
  • Clarified the distinction between activation combinators and hooks in the hooks documentation.

These changes collectively improve the safety, composability, and clarity of the component activation system, and ensure that both the implementation and documentation are robust against common errors.

hovsep and others added 4 commits July 30, 2026 20:38
A payload is an any, because a mesh carries mixed types down one pipe. Every
component that reads one therefore has to get it back out, and a bare type
assertion is either unchecked -- and takes down the whole run when something
upstream changes its payload type -- or checked, and three lines every time.

As[T] reports what went wrong, AsOrDefault carries on with a default, and
neither panics on a nil signal or a nil payload. The per-type shorthands wrap
only the fallible form: AsOrDefault already infers T from the default, so an
AsIntOrDefault would be longer than the generic it wraps. AsFloat64OrDefault
is the one exception, because an untyped 0 infers int and AsOrDefault(s, 0)
would silently return the default for a perfectly good float64 payload.

AsNumber is the loose one, widening float32/int/int64/uint64 and encoding
bool as 1 and 0. It answers "is this a measurement at all" for code that does
not know which components produce which payloads -- a structured signal often
uses its payload as a type tag and keeps the values in scalars.

The README, the runnable Example and the quick-start now read payloads this
way instead of asserting on PayloadOrNil.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Wiring code reads as a list of edges, and a bare error from PipeTo gives no
clue which of a dozen lines produced it. MultiPipe takes the list and names
the edge that failed; MultiForward does the same for the forwarding case,
where signals are copied immediately rather than a connection registered.

A nil port on either end is reported rather than dereferenced. That is the
common case, not a defensive nicety: OutputByName and InputByName return nil
for a name no port has, so without the check a typo in a wiring list surfaces
as a nil dereference somewhere well past the typo, with nothing naming it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A component has one activation function, but the thing it does is often
several things in a fixed order -- read the controls, advance the state,
publish the result -- and writing them as one closure is how a component
grows to two hundred lines with no seam anywhere. Sequential, When,
RequireInputs and Pipeline build the single function a component is
constructed with. They are values passed to WithActivationFunc, not hooks:
OnActivation stays the tool for behavior added from outside the component.

When and RequireInputs guard on inputs differently, and the distinction is
easy to get backwards. When skips the activation, so a partial set of inputs
is cleared at drain time and never comes back; RequireInputs suspends and
keeps what already arrived.

Port names are resolved before any signal is looked at. Collection.ByNames
silently skips names it cannot find, and AllHaveSignals on the resulting
empty collection is vacuously true, so ByNames("typo").AllHaveSignals()
reports ready and the guard quietly becomes a no-op. RequireInputs fails on
such a name rather than suspending the component for the rest of the run --
nothing ever arrives on a port that does not exist -- and every name is
checked before any signal, or a port that is merely empty hides the typo
behind a wait. Pipeline likewise errors instead of dereferencing a nil port.

Pipeline reads its inputs in the order named rather than through the
collection's map iteration, so a stage that folds or pairs up its group gets
the caller's order rather than an arbitrary one, and a stage returning a nil
group is an error rather than a nil dereference at the output port.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
design.md gains the invariant behind the guard bug the combinators had to fix:
lookups by name are silently forgiving -- ByName returns nil, ByNames skips,
and Every on the empty result is vacuously true -- so anything taking port
names as strings must resolve them all before asking about signals. It also
records why AsFloat64OrDefault survives when its siblings were dropped, so
nobody restores the symmetry, and adds signal.As[T] to the approved-generics
list, which the accessors had quietly broken.

Comment hygiene gains a length rule. The three new files were first written
with multi-paragraph headers and per-function essays; that material is
documentation, and of the two copies the one in source is the one that rots.
One line is the default, a short second paragraph the ceiling, and anything
longer belongs in docs/wiki. The files were compacted to match: 46 lines of
comment removed, every constraint kept.

hooks.md separates OnActivation hooks from the combinators, naming.md covers
combinator naming and the component-level predicate, and testing.md requires
covering the name that resolves to no port -- the case whose absence let the
vacuous-truth bug through.

Also fixes signal.Group.ForEach in four wiki snippets that showed it
returning (*Group, error). It returns error only, so none of them compiled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@hovsep
hovsep enabled auto-merge (rebase) July 30, 2026 17:40
@github-actions

Copy link
Copy Markdown

Benchmark report (advisory)

Statistically significant changes: 9 regression(s), 17 improvement(s) (PR head vs. base branch).

Benchmark Metric Base PR Δ
MeshRunWide/10000-4 sec/op 47.91m ± 9% 51.87m ± 2% +8.26%
MeshFanIn/10-4 sec/op 62.70µ ± 1% 63.96µ ± 1% +2.01%
MeshConstructionScale/10-4 sec/op 30.73µ ± 1% 29.68µ ± 3% -3.42%
MeshConstructionScale/100-4 sec/op 301.3µ ± 1% 293.9µ ± 4% -2.44%
MeshConstructionScale/1000-4 sec/op 3.193m ± 1% 3.269m ± 4% +2.40%
MeshConstructionScale/10000-4 sec/op 36.00m ± 3% 37.14m ± 3% +3.18%
MeshRunPipeline-4 sec/op 110.4µ ± 2% 107.2µ ± 3% -2.90%
MeshRunFanOut-4 sec/op 57.71µ ± 2% 55.53µ ± 1% -3.78%
MeshConstruction-4 sec/op 31.01µ ± 4% 29.60µ ± 3% -4.57%
MeshThroughputDummy/mid-4 sec/op 71.67m ± 1% 70.62m ± 2% -1.47%
MeshThroughputBypass/mid-4 sec/op 191.6m ± 2% 196.7m ± 2% +2.70%
MeshThroughputBypass/huge-4 sec/op 2.353 ± 7% 2.526 ± 5% +7.34%
MeshConstructionScale/1000-4 B/op 2.874Mi ± 0% 2.874Mi ± 0% -0.00%
MeshThroughputDummy/mid-4 activations/s 1.402M ± 1% 1.423M ± 1% +1.49%
MeshThroughputBypass/mid-4 activations/s 524.6k ± 3% 510.8k ± 1% -2.63%
MeshThroughputBypass/huge-4 activations/s 427.1k ± 5% 397.9k ± 5% -6.84%
MeshThroughputDummy/mid-4 cycles/s 2.804k ± 1% 2.846k ± 1% +1.48%
MeshThroughputBypass/mid-4 cycles/s 1.049k ± 2% 1.022k ± 1% -2.62%
MeshThroughputBypass/huge-4 cycles/s 85.42 ± 5% 79.57 ± 5% -6.85%
ComponentHooks_Overhead/WithHooks-4 sec/op 118.3µ ± 2% 122.8µ ± 3% +3.81%
ComponentHooks_Overhead/WithHooks-4 B/op 175.6Ki ± 3% 165.6Ki
GroupCoWOps-4 sec/op 73.42µ ± 3% 72.06µ ± 0% -1.85%
GroupBuild/10-4 sec/op 3.050µ ± 1% 2.918µ ± 0% -4.34%
GroupBuild/100-4 sec/op 43.00µ ± 1% 40.67µ ± 1% -5.42%
GroupBuild/1000-4 sec/op 1.862m ± 9% 1.692m ± 3% -9.13%
GroupPayloadSize/1024-4 sec/op 1.208µ ± 0% 1.197µ ± 0% -0.91%
GroupPayloadSize/1048576-4 sec/op 1.262µ ± 1% 1.248µ ± 0% -1.03%

Higher is worse on every metric. allocs/op is the most reliable signal on shared CI runners; treat sec/op as guidance.

Full benchstat table
goos: linux
goarch: amd64
pkg: github.com/hovsep/fmesh
cpu: AMD EPYC 9V74 80-Core Processor                
                              │  base.txt   │              pr.txt               │
                              │   sec/op    │   sec/op     vs base              │
MeshRunWide/10-4                49.99µ ± 2%   49.53µ ± 1%       ~ (p=0.328 n=8)
MeshRunWide/100-4               283.0µ ± 1%   281.7µ ± 1%       ~ (p=0.505 n=8)
MeshRunWide/1000-4              3.081m ± 3%   3.110m ± 1%       ~ (p=0.645 n=8)
MeshRunWide/10000-4             47.91m ± 9%   51.87m ± 2%  +8.26% (p=0.000 n=8)
MeshFanIn/10-4                  62.70µ ± 1%   63.96µ ± 1%  +2.01% (p=0.001 n=8)
MeshFanIn/100-4                 424.2µ ± 2%   428.7µ ± 2%       ~ (p=0.195 n=8)
MeshFanIn/1000-4                7.157m ± 3%   7.266m ± 6%       ~ (p=0.505 n=8)
MeshFanIn/10000-4               422.1m ± 2%   432.3m ± 3%       ~ (p=0.083 n=8)
MeshConstructionScale/10-4      30.73µ ± 1%   29.68µ ± 3%  -3.42% (p=0.000 n=8)
MeshConstructionScale/100-4     301.3µ ± 1%   293.9µ ± 4%  -2.44% (p=0.021 n=8)
MeshConstructionScale/1000-4    3.193m ± 1%   3.269m ± 4%  +2.40% (p=0.010 n=8)
MeshConstructionScale/10000-4   36.00m ± 3%   37.14m ± 3%  +3.18% (p=0.028 n=8)
MeshRunPipeline-4               110.4µ ± 2%   107.2µ ± 3%  -2.90% (p=0.000 n=8)
MeshRunFanOut-4                 57.71µ ± 2%   55.53µ ± 1%  -3.78% (p=0.000 n=8)
MeshConstruction-4              31.01µ ± 4%   29.60µ ± 3%  -4.57% (p=0.000 n=8)
MeshThroughputDummy/small-4     8.693m ± 1%   8.598m ± 1%       ~ (p=0.195 n=8)
MeshThroughputDummy/mid-4       71.67m ± 1%   70.62m ± 2%  -1.47% (p=0.002 n=8)
MeshThroughputDummy/huge-4      768.4m ± 5%   766.9m ± 3%       ~ (p=0.798 n=8)
MeshThroughputBypass/small-4    22.46m ± 1%   22.57m ± 1%       ~ (p=0.382 n=8)
MeshThroughputBypass/mid-4      191.6m ± 2%   196.7m ± 2%  +2.70% (p=0.007 n=8)
MeshThroughputBypass/huge-4      2.353 ± 7%    2.526 ± 5%  +7.34% (p=0.000 n=8)
geomean                         3.427m        3.443m       +0.48%

                              │   base.txt    │                pr.txt                 │
                              │     B/op      │     B/op       vs base                │
MeshRunWide/10-4                 16.11Ki ± 0%    16.11Ki ± 0%       ~ (p=1.000 n=8)
MeshRunWide/100-4                152.5Ki ± 0%    152.5Ki ± 0%       ~ (p=0.701 n=8)
MeshRunWide/1000-4               1.503Mi ± 0%    1.503Mi ± 0%       ~ (p=0.645 n=8)
MeshRunWide/10000-4              15.44Mi ± 0%    15.45Mi ± 0%       ~ (p=0.574 n=8)
MeshFanIn/10-4                   23.41Ki ± 0%    23.41Ki ± 0%       ~ (p=1.000 n=8) ¹
MeshFanIn/100-4                  289.5Ki ± 0%    289.5Ki ± 0%       ~ (p=0.945 n=8)
MeshFanIn/1000-4                 10.18Mi ± 0%    10.18Mi ± 0%       ~ (p=0.524 n=8)
MeshFanIn/10000-4                838.2Mi ± 0%    838.2Mi ± 0%       ~ (p=0.328 n=8)
MeshConstructionScale/10-4       29.89Ki ± 0%    29.89Ki ± 0%       ~ (p=1.000 n=8) ¹
MeshConstructionScale/100-4      290.6Ki ± 0%    290.6Ki ± 0%       ~ (p=0.467 n=8)
MeshConstructionScale/1000-4     2.874Mi ± 0%    2.874Mi ± 0%  -0.00% (p=0.017 n=8)
MeshConstructionScale/10000-4    28.60Mi ± 0%    28.60Mi ± 0%       ~ (p=0.059 n=8)
MeshRunPipeline-4                35.57Ki ± 0%    35.57Ki ± 0%       ~ (p=1.000 n=8) ¹
MeshRunFanOut-4                  18.11Ki ± 0%    18.11Ki ± 0%       ~ (p=1.000 n=8) ¹
MeshConstruction-4               29.89Ki ± 0%    29.89Ki ± 0%       ~ (p=1.000 n=8) ¹
MeshThroughputDummy/small-4      2.779Mi ± 0%    2.779Mi ± 0%       ~ (p=0.279 n=8)
MeshThroughputDummy/mid-4        30.50Mi ± 0%    30.50Mi ± 0%       ~ (p=0.234 n=8)
MeshThroughputDummy/huge-4       294.0Mi ± 0%    294.0Mi ± 0%       ~ (p=0.721 n=8)
MeshThroughputBypass/small-4     9.967Mi ± 0%    9.967Mi ± 0%       ~ (p=0.665 n=8)
MeshThroughputBypass/mid-4       102.4Mi ± 0%    102.4Mi ± 0%       ~ (p=0.721 n=8)
MeshThroughputBypass/huge-4     1012.9Mi ± 0%   1012.9Mi ± 0%       ~ (p=0.161 n=8)
geomean                          1.925Mi         1.925Mi       +0.00%
¹ all samples are equal

                              │  base.txt   │               pr.txt                │
                              │  allocs/op  │  allocs/op   vs base                │
MeshRunWide/10-4                 530.0 ± 0%    530.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshRunWide/100-4               4.862k ± 0%   4.862k ± 0%       ~ (p=1.000 n=8) ¹
MeshRunWide/1000-4              48.99k ± 0%   48.99k ± 0%       ~ (p=0.740 n=8)
MeshRunWide/10000-4             490.3k ± 0%   490.3k ± 0%       ~ (p=0.667 n=8)
MeshFanIn/10-4                   744.0 ± 0%    744.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshFanIn/100-4                 6.699k ± 0%   6.699k ± 0%       ~ (p=1.000 n=8) ¹
MeshFanIn/1000-4                67.03k ± 0%   67.03k ± 0%       ~ (p=0.392 n=8)
MeshFanIn/10000-4               670.2k ± 0%   670.1k ± 0%       ~ (p=0.313 n=8)
MeshConstructionScale/10-4       854.0 ± 0%    854.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshConstructionScale/100-4     8.240k ± 0%   8.240k ± 0%       ~ (p=1.000 n=8) ¹
MeshConstructionScale/1000-4    82.95k ± 0%   82.95k ± 0%       ~ (p=1.000 n=8) ¹
MeshConstructionScale/10000-4   830.0k ± 0%   830.0k ± 0%       ~ (p=1.000 n=8) ¹
MeshRunPipeline-4                980.0 ± 0%    980.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshRunFanOut-4                  572.0 ± 0%    572.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshConstruction-4               854.0 ± 0%    854.0 ± 0%       ~ (p=1.000 n=8) ¹
MeshThroughputDummy/small-4     67.15k ± 0%   67.15k ± 0%       ~ (p=0.637 n=8)
MeshThroughputDummy/mid-4       621.6k ± 0%   621.6k ± 0%       ~ (p=0.234 n=8)
MeshThroughputDummy/huge-4      6.153M ± 0%   6.153M ± 0%       ~ (p=0.721 n=8)
MeshThroughputBypass/small-4    337.8k ± 0%   337.8k ± 0%       ~ (p=0.738 n=8)
MeshThroughputBypass/mid-4      3.328M ± 0%   3.328M ± 0%       ~ (p=0.700 n=8)
MeshThroughputBypass/huge-4     33.22M ± 0%   33.22M ± 0%       ~ (p=0.161 n=8)
geomean                         43.89k        43.89k       -0.00%
¹ all samples are equal

                             │   base.txt    │               pr.txt                │
                             │ activations/s │ activations/s  vs base              │
MeshThroughputDummy/small-4      1.156M ± 2%     1.169M ± 2%       ~ (p=0.195 n=8)
MeshThroughputDummy/mid-4        1.402M ± 1%     1.423M ± 1%  +1.49% (p=0.002 n=8)
MeshThroughputDummy/huge-4       1.308M ± 4%     1.311M ± 2%       ~ (p=0.798 n=8)
MeshThroughputBypass/small-4     447.6k ± 1%     445.2k ± 1%       ~ (p=0.382 n=8)
MeshThroughputBypass/mid-4       524.6k ± 3%     510.8k ± 1%  -2.63% (p=0.007 n=8)
MeshThroughputBypass/huge-4      427.1k ± 5%     397.9k ± 5%  -6.84% (p=0.000 n=8)
geomean                          772.6k          763.0k       -1.25%

                             │  base.txt   │              pr.txt               │
                             │  cycles/s   │  cycles/s    vs base              │
MeshThroughputDummy/small-4    23.12k ± 2%   23.38k ± 2%       ~ (p=0.195 n=8)
MeshThroughputDummy/mid-4      2.804k ± 1%   2.846k ± 1%  +1.48% (p=0.002 n=8)
MeshThroughputDummy/huge-4      261.6 ± 4%    262.1 ± 2%       ~ (p=0.798 n=8)
MeshThroughputBypass/small-4   8.951k ± 1%   8.905k ± 1%       ~ (p=0.398 n=8)
MeshThroughputBypass/mid-4     1.049k ± 2%   1.022k ± 1%  -2.62% (p=0.005 n=8)
MeshThroughputBypass/huge-4     85.42 ± 5%    79.57 ± 5%  -6.85% (p=0.000 n=8)
geomean                        1.545k        1.526k       -1.25%

pkg: github.com/hovsep/fmesh/integration_tests/component_hooks
                                       │  base.txt   │              pr.txt               │
                                       │   sec/op    │   sec/op     vs base              │
ComponentHooks_Overhead/WithoutHooks-4   122.4µ ± 2%   124.1µ ± 4%       ~ (p=0.195 n=8)
ComponentHooks_Overhead/WithHooks-4      118.3µ ± 2%   122.8µ ± 3%  +3.81% (p=0.005 n=8)
geomean                                  120.3µ        123.4µ       +2.60%

                                       │   base.txt    │               pr.txt                │
                                       │     B/op      │     B/op       vs base              │
ComponentHooks_Overhead/WithoutHooks-4   192.5Ki ± 10%   190.1Ki ± 12%       ~ (p=0.234 n=8)
ComponentHooks_Overhead/WithHooks-4      175.6Ki ±  3%   165.6Ki ±  4%  -5.72% (p=0.000 n=8)
geomean                                  183.8Ki         177.4Ki        -3.51%

                                       │  base.txt  │               pr.txt               │
                                       │ allocs/op  │ allocs/op   vs base                │
ComponentHooks_Overhead/WithoutHooks-4   18.00 ± 0%   18.00 ± 0%       ~ (p=1.000 n=8) ¹
ComponentHooks_Overhead/WithHooks-4      18.00 ± 0%   18.00 ± 0%       ~ (p=1.000 n=8) ¹
geomean                                  18.00        18.00       +0.00%
¹ all samples are equal

pkg: github.com/hovsep/fmesh/signal
                           │  base.txt   │              pr.txt               │
                           │   sec/op    │   sec/op     vs base              │
GroupCoWOps-4                73.42µ ± 3%   72.06µ ± 0%  -1.85% (p=0.005 n=8)
GroupScalarAggregation-4     2.249µ ± 2%   2.227µ ± 1%       ~ (p=0.083 n=8)
GroupBuild/10-4              3.050µ ± 1%   2.918µ ± 0%  -4.34% (p=0.000 n=8)
GroupBuild/100-4             43.00µ ± 1%   40.67µ ± 1%  -5.42% (p=0.000 n=8)
GroupBuild/1000-4            1.862m ± 9%   1.692m ± 3%  -9.13% (p=0.001 n=8)
GroupBuild/10000-4           469.0m ± 2%   465.4m ± 2%       ~ (p=0.279 n=8)
GroupPayloadSize/8-4         1.203µ ± 0%   1.198µ ± 1%       ~ (p=0.059 n=8)
GroupPayloadSize/1024-4      1.208µ ± 0%   1.197µ ± 0%  -0.91% (p=0.000 n=8)
GroupPayloadSize/65536-4     1.206µ ± 0%   1.200µ ± 1%       ~ (p=0.113 n=8)
GroupPayloadSize/1048576-4   1.262µ ± 1%   1.248µ ± 0%  -1.03% (p=0.001 n=8)
geomean                      23.02µ        22.43µ       -2.57%

                           │    base.txt    │                pr.txt                │
                           │      B/op      │     B/op      vs base                │
GroupCoWOps-4                137.1Ki ± 0%     137.1Ki ± 0%       ~ (p=1.000 n=8)
GroupScalarAggregation-4       0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/10-4              4.266Ki ± 0%     4.266Ki ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/100-4             116.0Ki ± 0%     116.0Ki ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/1000-4            8.493Mi ± 0%     8.493Mi ± 0%       ~ (p=0.222 n=8)
GroupBuild/10000-4           820.7Mi ± 0%     820.7Mi ± 0%       ~ (p=0.314 n=8)
GroupPayloadSize/8-4         2.422Ki ± 0%     2.422Ki ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/1024-4      2.422Ki ± 0%     2.422Ki ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/65536-4     2.422Ki ± 0%     2.422Ki ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/1048576-4   2.422Ki ± 0%     2.422Ki ± 0%       ~ (p=1.000 n=8) ¹
geomean                                   ²                 -0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                           │   base.txt    │               pr.txt                │
                           │   allocs/op   │  allocs/op   vs base                │
GroupCoWOps-4                1.635k ± 0%     1.635k ± 0%       ~ (p=1.000 n=8) ¹
GroupScalarAggregation-4      0.000 ± 0%      0.000 ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/10-4               131.0 ± 0%      131.0 ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/100-4             1.301k ± 0%     1.301k ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/1000-4            13.74k ± 0%     13.74k ± 0%       ~ (p=1.000 n=8) ¹
GroupBuild/10000-4           139.8k ± 0%     139.8k ± 0%       ~ (p=0.524 n=8)
GroupPayloadSize/8-4          31.00 ± 0%      31.00 ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/1024-4       31.00 ± 0%      31.00 ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/65536-4      31.00 ± 0%      31.00 ± 0%       ~ (p=1.000 n=8) ¹
GroupPayloadSize/1048576-4    31.00 ± 0%      31.00 ± 0%       ~ (p=1.000 n=8) ¹
geomean                                  ²                +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@hovsep
hovsep disabled auto-merge July 30, 2026 18:03
@hovsep
hovsep merged commit 30a6b92 into main Jul 30, 2026
4 checks passed
@hovsep
hovsep deleted the new_helpers branch July 30, 2026 18:03
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.

1 participant