Live data from Hacker News

Zero-cost futures in Rust

aturon.github.io

61–70 of 348 posts

Re: Zero-cost futures in Rust

#61
post #42

I dabbled with rust in the past and was really fascinated with it, but haven't played around lately. One thing caught my eye in the post: fn get_row(id: i32) -> impl Future ; That return type looks odd to me. What does it mean to return an "impl", and is that a new feature in rust, or just something advanced that I missed in my exploration before?

On a related note: why `Future ` instead of `Future `? I notice it's consistent with the standard `Iterator `, but why is Iterator like that?

[deleted]

Re: Zero-cost futures in Rust

#62
post #43

Earlier quoted context omitted.

What sort of syntax support do you have in mind? (Personally I think any language-level support is unlikely, given that Rust doesn't make a point of privileging any particular approach to concurrency.)

See Python 3.5, ES6 and C# and their await stuff. They generally use a form of future internally to abstract this.

Ah yes, I wasn't thinking of async/await. I suppose there's enough precedence from other languages to warrant that, though this is probably far-future work (I don't even expect futures to land in the stdlib for quite a while, though I would like them to eventually).

Re: Zero-cost futures in Rust

#63

Finally a nice async/io interface for rust, always felt that it was a big missing piece, couple of questions for peps familiar with async in other languages : 1 - Isn't the state machine approach the same as C#/.net async/await is using ? But the with the added convenience of the syntactic sugar ? 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? 3 - I would have love some comparison (…

> 2 - no allocation : , does'nt the lambda closure need to be allocated somewhere ? I expect it is embedded in the state machine structure. In Rust (and C++) lambdas/closures are "value types".

In C++ lambdas have limited size (about 3 machine words). If it's context is larger than that, the data may be allocated on heap (if compiler can't optimize that allocation out).

Re: Zero-cost futures in Rust

#65

I'm rather surprised by the benchmark; I would expect the Go benchmark to be faster than Java (and the fact that it isn't may indicate some improvements that can be done to fasthttp by learning from rapidoid or minihttp). Then again, the difference isn't that much, so it just could be implementation details that would require a total refactor to fix.

Why would you expect that? AFAIK the Go compiler has a worse optimizer, a worse GC (at least throughput-wise) and possibly also a worse threading runtime. Since the benchmark measures steady-state performance and not memory or latency, and with the best Java server (probably optimized to almost never allocate) then Java having better code generation and threading could give it that much of an edge.

Go GCs fewer things, though. At least in my experience -- this isn't a hard fact :)

To me, Go feels like C-but-some-things-are-GCd, which Java is not. The explicit sharing annotations in Go means that it's super easy for it to not put most of the things on the GC heap, and it's super easy for me, the programmer, to see what's not being put on the GC heap. Whenever I've debugged Go code this been validated.

But yes, it's not as clear cut. I ignored the threading runtime being a factor, and ignored that Java has a better GC (though it GCs more things).

I also ignored JIT as steve pointed out to me in irc.

So yeah, there could be language reasons behind the benchmark order too. Worth investigating though, I'm sure the folks using fasthttp would love a perf boost :)

Re: Zero-cost futures in Rust

#67

Earlier quoted context omitted.

That is new syntax which has been accepted as a language change, but has not actually landed in the compiler yet. It was shown this way because it's much easier to understand, but is the same thing as it would be in the real code. https://github.com/rust-lang/rfcs/blob/master/text/1522-cons... is an explanation of the feature in detail, but it boils down to "I will return you some kind of thing that implements the Fu…

Does the need for this arise, in some sense, because Rust doesn't offer classical inheritance and so no mechanism to indicate co/contra variance?

Rust does let you communicate variance (it's very important for lifetimes). Variance is determined based on a type's composition, and PhantomData can be used to specify variance that doesn't immediately follow by providing an "example" of what it should behave like. The only limitation of this approach is that you can't override the compiler's reasoning -- if it sees evidence for covariance, and you provide more evidence for contravariance it will just give up and pick invariance (which is of course strictly correct if both pieces of evidence are accurate). Also I guess you can't have bivariance but like... bivariance is so bad.

All of Rust's standard collection and smaht pointer types are written in pure Rust and have relatively complex variance behaviour.

Re: Zero-cost futures in Rust

#68
post #45

Earlier quoted context omitted.

that sounds great but I guess that will make the compilation time bigger.

In Rust it's frequently the case that slow compilations are dominated by generating and optimizing LLVM IR. This codegen step (generating LLVM IR) often takes awhile just because we're generating so much IR. Rust takes an approach with generic functions called monomorphization which means that we generate a new version of each function for each set of generics it's instantiated with. This means that a future of a Str…

Do note that with MIR the focus is polymorphic optimizations - reducing the LLVM IR for all monomorphizations of a generic function, at once.

Unlike C++ templates, Rust enforces a single definition with uniform semantics, for a generic type/function (specialization going through the existing trait static dispatch mechanism), so we can take advantage of that to reduce compile times.

Re: Zero-cost futures in Rust

#69

TLDR; I’ve claimed a few times that our futures library provides a zero-cost abstraction, in that it compiles to something very close to the state machine code you’d write by hand. To make that a bit more concrete: - None of the future combinators impose any allocation. When we do things like chain uses of and_then, not only are we not allocating, we are in fact building up a big enum that represents the state machin…

Generating state machine out of async fluent APIs was enlightening.

How are are handling errors ? - One Error state with the context ?

Re: Zero-cost futures in Rust

#70
post #40

Earlier quoted context omitted.

You can indeed use this on stable Rust today! Right now 1.9.0 is the minimum supported version due to the usage of `catch_panic` in a few places. I'd recommend a beta compiler for now though to compile some of the examples. There's a bug in the stable compiler which causes them to take up to 8x longer to compile, but beta/nightly are both speedy!

How do futures deal with panics? - should they even?

Panics are caught at the "task" level -- and there's usually one task per connection. They don't take down the entire server (since tasks are isolation boundaries).

Right now, nothing happens with the panic after it's caught, but we want to add hooks for doing something with it. Coming soon!

Post reply on HN