Open
Description
Maybe a duplicate of #52924, but maybe also something else.
I observed that the sizes of Future
s 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
Labels
Area: Async & AwaitArea: CoroutinesAsync-await issues that have been triaged during a working group meeting.Category: An issue proposing an enhancement or a PR with one.Category: An issue highlighting optimization opportunities or PRs implementing suchIssue: Problems and improvements with respect to binary size of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.