Skip to content

async is not zero-cost #1571

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

Closed
kpp opened this issue Apr 28, 2019 · 8 comments
Closed

async is not zero-cost #1571

kpp opened this issue Apr 28, 2019 · 8 comments

Comments

@kpp
Copy link
Contributor

kpp commented Apr 28, 2019

See my post https://www.reddit.com/r/rust/comments/bi9yzs/async_is_not_zerocost/.

Long story short, given the most simple function future::ready among all combinators:

pub async fn ready<T>(value: T) -> T {
    value
}

I benchmarked it against https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.15/futures/future/fn.ready.html. with:

executor::block_on(async {
   for _ in 1..n {
       await!(ready(42));
   }
});

Conclusion:

futures-rs is ~1.85 faster than async version of ready without lto and ~1.20 times faster with lto.

I hope the compiler and futures-rs teams will dig into what's going on and why async fn slows down the code a little bit.

@lnicola
Copy link
Member

lnicola commented Apr 28, 2019

CC @cramertj, @stjepang since TLS came up in rust-lang/rust#59119.

@kpp
Copy link
Contributor Author

kpp commented Apr 28, 2019

since TLS came up in rust-lang/rust#59119.

thread_local! {
-    static TLS_WAKER: Cell<Option<NonNull<Waker>>> = Cell::new(None);
+    static TLS_CX: Cell<Option<NonNull<Context<'static>>>> = Cell::new(None);
}

Wasn't TLS before?

@yoshuawuyts
Copy link
Member

yoshuawuyts commented Apr 29, 2019

Congrats, @rust-lang-nursery and personally @alexcrichton , your futures' combinators are faster than async/await solution.

@kpp I feel you're coming off rather hostile here.

Even if you didn't intend to come off that way, the fact that it can be interpreted as such adds unnecessary tension to what is essentially a bug report.

I'm sure the futures team would be happy to help get at the bottom of any (perceived) performance regressions, as everyone here wants async rust to be as good as possible. But that requires at the very least we maintain a base level of respect towards each other.

@kpp
Copy link
Contributor Author

kpp commented Apr 29, 2019

I feel you're coming off rather hostile here.

I am sorry, I did not want to hurt anyone.

From Urban Dictionary:

Congrats is a term used to sarcastically congratulate someone on an achievement...

@yoshuawuyts I was told about this meaning in a private conversation. I am not a native English speaker, I did not mean to hurt anyone.

@cramertj
Copy link
Member

One easy answer here is that the structure we generate for futures::future::Ready<T> is basically just Option<T>, which is pretty well optimized. By contrast, async fn ready<T>(x: T) { x } turns into sometihng like struct ReadyGenerator<T> { state: i32, x: T } where x is a maybe-invalid T. That, combined with the current use of TLS, makes it pretty unsurprising to me that there'd be a performance difference in this super-micro benchmark. TBH I'm surprised the difference isn't bigger. Without things like the optimizations @tmandry has been working on over in rust-lang/rust#52924, I'd expect futures combinators (which are just about as optimized as it is possible to be) to continue being more performant than async/await generated code. These limitations aren't fundamental, though, and I'm looking forward to continued improvements here.

I'm going to close this issue, since it doesn't really represent any particular bug. The other bits of work I've mentioned above (generator representation, TLS) are already tracked in other issues.

@kpp
Copy link
Contributor Author

kpp commented Apr 29, 2019

Thanks

@yoshuawuyts
Copy link
Member

yoshuawuyts commented Apr 29, 2019

I am not a native English speaker, I did not mean to hurt anyone.

@kpp No worries, glad it was just a misunderstanding!

@Pauan
Copy link

Pauan commented Apr 30, 2019

@kpp I was told about this meaning in a private conversation. I am not a native English speaker, I did not mean to hurt anyone.

To be clear, the issue isn't with the word "congrats" (which is fine).

The issue is that it portrayed futures-rs as competing with async/await, which isn't correct: the futures-rs team works closely together with the Rust lang team, and people like @alexcrichton have done a lot of work on futures-rs and the Rust compiler.

So it's not really competing at all, there's a lot of overlap between futures-rs and Rust itself.

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

No branches or pull requests

5 participants