Live data from Hacker News

Zero-cost futures in Rust

aturon.github.io

131–140 of 348 posts

Re: Zero-cost futures in Rust

#131
post #88

Earlier quoted context omitted.

A "zero-cost abstraction" really means that abstraction doesn't impose a cost over the optimal implementation of the task it is abstracting. Some things—like chaining a dynamic number of (arbitrary) closures—fundamentally require some sort of dynamic allocation/construction, and so a zero-cost abstraction would be one that it only does that dynamic behaviour when necessary. If you don't need the dynamic behaviour, th…

Thanks for your reply. I'm still trying to understand what the restrictions look like. Say I sometimes have an outstanding asynchronous operation, i.e. validating some text in a document. I want to represent this by storing a Future representing this operation: struct Document { text:String, validating: Option > }; It seems like there's a problem: in order to have a struct of this type, we need to have the type of th…

One solution is to put the Future into a Box.

Re: Zero-cost futures in Rust

#132
post #122

Earlier quoted context omitted.

> So wondering if Rust provides any ability to add that kind of an N:M threading approach. Perhaps via an extension, macro or some other mechanism. I don't want M:N threading as Go implements it. It's a big loss of performance for marginal benefit over futures. In particular the libmill approach was tried in Rust and the results were far worse than 1:1. However, assuming this takes off I would like to see async/await…

> I don't want M:N threading as Go implements it. As someone who writes code for enterpricey businesses doing a lot of I/O bound stuff, golang style M:N threading is a godsend over Java's standard library, and other common platforms in that space. Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome. With futures, the…

Well, one of the problems with M:N threading is that the "switch into C for that part" gets a lot more expensive, negating the speed increase.

Re: Zero-cost futures in Rust

#133
post #76

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.

You may find this makes somewhere more sense to think of it as ~5.3 microseconds per request for fasthttp vs. ~4.8 microseconds for Java vs. ~4.3 for Rust. It's 40 microseconds or so for the standard lib Go. I'm just eyeballing the graph but this should be close enough (dominated by local CPU variances and such). Just as some people point out that "gallons per mile" is a more intuitively useful way of thinking, I thi…

>> "I fear, based on experience, that some developers well be looking at this and will sit there trying to choose..."

Sure, but it's not the responsibility of this blog post to protect bad/lazy engineers from themselves.

Re: Zero-cost futures in Rust

#134
post #122

Earlier quoted context omitted.

> So wondering if Rust provides any ability to add that kind of an N:M threading approach. Perhaps via an extension, macro or some other mechanism. I don't want M:N threading as Go implements it. It's a big loss of performance for marginal benefit over futures. In particular the libmill approach was tried in Rust and the results were far worse than 1:1. However, assuming this takes off I would like to see async/await…

> I don't want M:N threading as Go implements it. As someone who writes code for enterpricey businesses doing a lot of I/O bound stuff, golang style M:N threading is a godsend over Java's standard library, and other common platforms in that space. Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome. With futures, the…

> Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome.

You don't gain as much performance. On Linux, you don't actually gain that much if anything over 1:1 threading. Most of the benefits of goroutines actually comes from the small stacks, which don't have anything to do with M:N and 1:1 to begin with—they're a feature of GC.

As the blog post states, our end goal is to achieve the ergonomics of Go-style M:N without sacrificing nginx levels of performance. With this futures library, we've established the foundations. It would make no sense to give up before even trying.

> And if I need anything better performing, I can still switch to C for specific use cases.

Why would you write networking code in C in 2016, when there are better alternatives available (like this one)?

Rust's philosophy is to have both performance and ergonomics. It rejects the idea that optimal performance requires a cumbersome programming model. I'm not about to give up on that.

Re: Zero-cost futures in Rust

#135
post #74

Earlier quoted context omitted.

I'm... curious about why you think LLVM isn't used to the sort of code that results from these sort of zero-cost abstractions: C++ code is also very aggressive about templates that inline away to nothing, and modern C++ especially has many similar abstractions to Rust (cf. closures, and the range proposal). Rust isn't special in that particular regard. Maybe you mean LLVM is very low-level and thus it sees everything…

I believe he meant, lots of closures. Which is not normal in C or C++, but is the normal in Rust because they are Zero-Cost. Without knowing anything about LLVM's internals, I would assume it doesn't anticipate so much closure chaining, and therefore doesn't leverage the fact that they are so easy to inline.

Lambdas in C++ are almost identical to Rust ones (each closure is a unique unnameable struct containing the captures, with an overloaded operator()), in fact, the current Rust scheme was explicitly inspired by C++11 closures. Historically (C++98), it's true that not much code used closures, because they didn't exist at a language level, but the modern language uses them much more aggressively, even pushing hard on making them more and more flexible (e.g. auto/generic closures in C++14). For instance, sort[1] can take a closure which is more efficient that way than a function pointer, and easier to use than a manually implemented custom type.

Also, closures are just structs with functions that take them as arguments, so if the compiler can handle those, it can handle closures.

[1]: http://en.cppreference.com/w/cpp/algorithm/sort

Re: Zero-cost futures in Rust

#136
post #20

Is there any special handling for Futures that complete with an error? Also, how do you debug code that's hung or taking too long? It might be useful to get a list of all the jobs (incomplete Futures) that are currently running, much like running 'ps'.

Yes -- the blog post didn't go into details about this, but Futures in general have an error type as well, and all the combinators know how to propagate errors correctly. (There's also a notion of "cancellation" for a future -- we'll get into this with later posts). In terms of debugging, there's not infrastructure currently, but the kind of thing you're talking about should be easy to add!

It would be useful to give a Future a name (for debugging) in the code that creates it, so a list of "pending jobs" is more readable. I don't think any other language is doing that.

Like other kinds of debugging info, you might also want a way to strip out the job names in a production build.

Re: Zero-cost futures in Rust

#137

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.

Add around 10-30% (but are cases of even 150%) of speed up in Go 1.7 that will be released next week.

Re: Zero-cost futures in Rust

#138
post #42

Earlier quoted context omitted.

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

Because it's an associated type ( https://doc.rust-lang.org/book/associated-types.html ), not a regular generic parameter.

Aren't generic types with one associated type isomorphic to 'normal' generic types? In that sense, it is still odd.

Re: Zero-cost futures in Rust

#139
post #84

As mentioned in the post, given Rust wants to operate in the same space as C, this approach makes sense. However from a higher level, building more complex concurrent systems, dealing with futures/deferred-s/promises and/or a central select/epoll/kqueue reactor loop gets daunting and doesn't mix with complex business rules. Deferred based approach has been a round for many years. I experienced it by using Twisted (Py…

> So wondering if Rust provides any ability to add that kind of an N:M threading approach. Perhaps via an extension, macro or some other mechanism. I don't want M:N threading as Go implements it. It's a big loss of performance for marginal benefit over futures. In particular the libmill approach was tried in Rust and the results were far worse than 1:1. However, assuming this takes off I would like to see async/await…

> ergonomics of languages like Erlang and Go

My brain read that as "ergolangmics"

Re: Zero-cost futures in Rust

#140
post #84

As mentioned in the post, given Rust wants to operate in the same space as C, this approach makes sense. However from a higher level, building more complex concurrent systems, dealing with futures/deferred-s/promises and/or a central select/epoll/kqueue reactor loop gets daunting and doesn't mix with complex business rules. Deferred based approach has been a round for many years. I experienced it by using Twisted (Py…

> So wondering if Rust provides any ability to add that kind of an N:M threading approach. Perhaps via an extension, macro or some other mechanism. I don't want M:N threading as Go implements it. It's a big loss of performance for marginal benefit over futures. In particular the libmill approach was tried in Rust and the results were far worse than 1:1. However, assuming this takes off I would like to see async/await…

[deleted]
Post reply on HN