Skip to content

Generator size: borrowed variables are assumed live across following yield points #59087

Open
@Matthias247

Description

@Matthias247

Maybe a duplicate of #52924, but maybe also something else.

I observed that the sizes of Futures generated by async fns can grow exponentially.
The following code shows an async fn, which produces a 1kB future. Each layering in another async fn doubles it's size:

#![feature(async_await)]

async fn i_am_1kb() -> bool
{
    let x: [u8; 1*1024] = [0; 1*1024];
    async{}.await;
    let _sum: u8 = x.iter().sum();
    true
}

fn main() {
    let fut1 = i_am_1kb();
    dbg!(std::mem::size_of_val(&fut1));

    let composed_1 = async {
        let inner = i_am_1kb();
        inner.await;
    };
    dbg!(std::mem::size_of_val(&composed_1));

    let composed_2 = async {
        let inner = i_am_1kb();
        dbg!(std::mem::size_of_val(&inner));
        inner.await;
    };
    dbg!(std::mem::size_of_val(&composed_2));

    let composed_3 = async {
        let inner = async {
            let inner = async {
                i_am_1kb().await;
            };
            dbg!(std::mem::size_of_val(&inner));
            inner.await;
        };
        dbg!(std::mem::size_of_val(&inner));
        inner.await;
    };
    dbg!(std::mem::size_of_val(&composed_3));
}

Output:

[src/main.rs:16] std::mem::size_of_val(&fut1) = 1032
[src/main.rs:22] std::mem::size_of_val(&composed_1) = 1036
[src/main.rs:29] std::mem::size_of_val(&composed_2) = 2072
[src/main.rs:44] std::mem::size_of_val(&composed_3) = 4168

It doesn't matter whether the statement between the future generation and await! references the future or not. A simply println("") will have the same effect.
Only if the future is directly awaited (as in composed_1) the size will stay constant.

cc @cramertj , @nikomatsakis , @Nemo157

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-coroutinesArea: CoroutinesAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions