Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only iterate through subfutures/substreams that have woken #119

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

wishawa
Copy link
Contributor

@wishawa wishawa commented Jan 10, 2023

This is dependent on #118.
This is a large PR, containing the primary change from #115.

Benchmark

after = this PR
before = #118

$ critcmp  after before 
group                after                                  before
-----                -----                                  ------
array::join 10       1.00  1571.1±42.20ns        ? ?/sec    1.19  1870.7±110.38ns        ? ?/sec
array::join 100      1.00     17.8±0.47µs        ? ?/sec    1.08     19.2±0.66µs        ? ?/sec
array::join 1000     1.00    186.5±3.93µs        ? ?/sec    7.62  1420.9±46.40µs        ? ?/sec
array::merge 10      1.00  1693.6±40.67ns        ? ?/sec    1.31      2.2±0.04µs        ? ?/sec
array::merge 100     1.00     18.3±0.40µs        ? ?/sec    2.23     40.7±1.25µs        ? ?/sec
array::merge 1000    1.00    185.0±6.82µs        ? ?/sec    11.60     2.1±0.12ms        ? ?/sec
array::race 10       1.00  1004.7±21.41ns        ? ?/sec    1.07  1076.1±17.76ns        ? ?/sec
array::race 100      1.00      7.3±0.55µs        ? ?/sec    1.54     11.3±0.29µs        ? ?/sec
array::race 1000     1.00     84.3±2.47µs        ? ?/sec    1.58    132.9±1.88µs        ? ?/sec
tuple::join 10       1.00  1616.3±34.23ns        ? ?/sec    1.21  1961.4±34.94ns        ? ?/sec
tuple::merge 10      1.00  1797.2±36.00ns        ? ?/sec    1.49      2.7±0.41µs        ? ?/sec
tuple::race 10       1.09  1137.1±19.05ns        ? ?/sec    1.00  1047.0±16.33ns        ? ?/sec
vec::join 10         1.00  1949.3±45.38ns        ? ?/sec    1.10      2.2±0.14µs        ? ?/sec
vec::join 100        1.00     15.4±0.65µs        ? ?/sec    1.83     28.1±0.77µs        ? ?/sec
vec::join 1000       1.00    169.5±4.55µs        ? ?/sec    10.07 1706.0±158.79µs        ? ?/sec
vec::merge 10        1.00      2.3±0.13µs        ? ?/sec    1.15      2.7±0.08µs        ? ?/sec
vec::merge 100       1.00     20.1±0.77µs        ? ?/sec    2.71     54.3±1.61µs        ? ?/sec
vec::merge 1000      1.00   212.5±11.80µs        ? ?/sec    15.92     3.4±0.08ms        ? ?/sec
vec::race 10         1.11  1178.7±19.01ns        ? ?/sec    1.00  1064.5±18.37ns        ? ?/sec
vec::race 100        1.00      6.4±0.11µs        ? ?/sec    1.73     11.1±0.15µs        ? ?/sec
vec::race 1000       1.00     61.6±1.98µs        ? ?/sec    1.99    122.8±1.09µs        ? ?/sec

As shown, the runtime now grows linearly with number of futures.

API changes

Tuples combinator now support more heterogeneous outputs, but in a more restricted way than #115 .

  • Join is heterogeneous (as it was before).
  • Race is homogeneous (as it was before).
  • TryJoin (previously not implemented) allows heterogeneous Ok types but only a single Error type.
  • RaceOk supports heterogeneous Error types but only a single Ok type.
    Making the remaining heterogeneous would require the select_types enum solution used in Waker optimization + O(woken) polling for every combinator except chain #115. I've been using that myself and find it clumsy- requiring weird enum matches and verbose type annotations.

For RaceOk, AggregateError has been unified-

For module instead of this PR uses
vec vec::AggregateError<E> AggregateError<Vec<E>>
array array::AggregateError<E, N> AggregateError<[E; N]>
tuple tuple::AggregateError<E, N> AggregateError<(E1, E2, ...)>

The new AggregateError is also simpler- instead of implementing Deref and DerefMut it now has public errors field.

Organizational changes

As in #115, the four future combinators are unified into a common module to avoid code duplication. In the future::common module, I implemented generic combinators whose behavior can be customized to match Join/Race/RaceOk/TryJoin via a generic type parameter.

@wishawa wishawa changed the title Only poll subfutures/substreams that have woken Only iterate through subfutures/substreams that have woken Jan 30, 2023
ControlFlow Continue/Break captures the Keep/EarlyReturn API in future::common better than Ok/Err.
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