9 ms·
Why would you want to do that in Rust instead of Go / Java / C# since the performance is the same. When I look at code example in the article the syntax is just
by Thaxll 9y ago
Why would you want to do that in Rust instead of Go / Java / C# since the performance is the same. When I look at code example in the article the syntax is just awful seriously, who want to write web services with that kind of syntax:
time_helpers::log_timed(&log.new(o!("step" => "upsert_episodes")), |_log| { }
It's just non-sense:
impl<S: server::State> actix_web::middleware::Middleware<S> for Middleware {
fn start(&self, req: &mut HttpRequest<S>) -> actix_web::Result<Started> {
let log = req.state().log().clone();
req.extensions().insert(Extension(log));
Ok(Started::Done)
}
Rust is a good language but I don't see it any time soon in the web space with that syntax and the lack of mature libraries, plus the time it takes to get anything done. Where I see it is more for super optimized things like serialization and the like as libraries but not as a main program.
- adrianN 9y agoTo learn Rust? Also, where do you get that the performance is the same? I didn't see any benchmarks.
- Thaxll 9y agoIn the linked article by the OP Java is faster than Rust in every scenarios. https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=json https://www.techempower.com/benchmarks/#section=data-r15&hw=... tbh benchmarks are not that useful, but it shows that GC languages are very fast in the web space and it's even more true when you add client -> server latency in the mix.
- staticassertion 9y agoNot in Plaintext. But yes, Java has some extremely optimized libraries for HTTP, and a great GC has a lot of advantages for this sort of benchmark I'd imagine (short lived allocations, deferred collections). That said, actix is particularly new, with room to optimize.
- seanmcdirmid 9y agoPeople often forget about the perf benefits of GC, focusing only on the overhead of collection. Still, you might be able to win in rust by using something like arenas when possible (though the type state system might not help in that case).
- steveklabnik 9y agoRust hasn't had typestate in something like four years now. Arenas and lifetimes work well together; the compiler actually has a hierarchy of arenas inside of it, and makes sure thanks to lifetimes that once the shorter-lived ones are freed, they don't get used again, for example.
- vardump 9y agoThe benchmark you linked has also latency tab. Try to press it. Looks like Rust libraries deliver very good latency with low jitter.
- swsieber 9y agoHeh, I bet rust also wins on memory usage by a land-slide.
- pcwalton 9y agoYou can write an overcomplicated framework in any language. Some of those Java frameworks are pretty impenetrable too. Here's an example of some Rust code that's even faster and is short and sweet: https://github.com/tokio-rs/tokio-minihttp/blob/master/examples/techempower.rs https://github.com/tokio-rs/tokio-minihttp/blob/master/examp... (I don't think the TechEmpower benchmarks really mean much, incidentally. They're so simple that they're way too easy to game.)
- bhauer 9y agoThe benchmarks establish a high-water mark and establish the magnitude of performance. Specific rank ordering is mostly a trivial matter, if admittedly a point of potentially fun competition. Some laser-focus on the plaintext benchmark in particular, presumably because it's the easiest to implement and the delightfully high numbers in the results are exciting. But more interesting are the test types that involve round-trips to the database, using an ORM (or similar), and other framework features. For me, the Fortunes test is the most interesting. Yes, it's "easy" to climb up a few positions and jockey for specific rank order against other similar contenders, but considering specific rank ordering is not a useful way to interpret the results. More useful is to see the orders of magnitude conveyed by the results. And it is not so easy for a low-performance platform (e.g., Ruby) to game its way into the top positions. See, for example, Java, Rust, and Ruby on the Fortunes test: https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=fortune&l=h7aqgv https://www.techempower.com/benchmarks/#section=data-r15&hw=... Obviously, no small benchmark can measure the performance characteristics of your application as implemented on multiple frameworks. But these are a proxy, and illustrate the performance landscape your application will exist within. They can reveal the bottlenecks your application will be unable to avoid in framework services such as JSON serialization, object-relational conversion, connection pooling, server-side templates, and so on.
- pcwalton 9y agoSure, but by the same token, you can't conclude Rust code is never faster than Go/Java/whatever for real-world code on account of some TechEmpower benchmark, as the parent poster was trying to do.
- staticassertion 9y agoNonsense to you is wonderful to me. I don't think "I am unfamiliar with this syntax" is really a useful observation - Erlang has an extremely unfamiliar syntax, but I don't think that makes it less suitable for building a service. To answer your question more directly (though I feel the article covers these points), as someone building services in rust, there are a few reason I'd choose Rust over the languages you listed: a) Largely deterministic performance Having written services professionally in Java I have seen performance scale linearly with connections, until one day it suddenly spikes massively - why? It was that we crossed some threshold where the GC was suddenly having to do a ton more work, which caused a serious feedback loop - server has to pause, clients don't handle it well, clients hammer server more, server has to pause, etc. You can have similar issues in Rust but they should be easier to spot (they should be less blow-up-y). b) Correctness/ Expressiveness (is this a word?) I find it far, far easier to write correct, expressive code in Rust. For example, I think anyone who has moved from Java 6 to 7 or 8 will admit that Optional is awesome - because it is. In Rust the pattern exposed by Optional is first class, and extends far beyond nullability. This is just one example though. I find it extremely easy, by comparison to other languages, to write Rust code in a 'type driven' way, and in my experience this is a huge part of (me) writing code with fewer defects. As the linked article puts it: > Constraints like a compiler and a discerning type system are tools that help us to find and think about those edges.
- danieldk 9y agoNonsense to you is wonderful to me. I don't think "I am unfamiliar with this syntax" is really a useful observation - Erlang has an extremely unfamiliar syntax, but I don't think that makes it less suitable for building a service. I do not think this is just about unfamiliarity. Doing static dispatch with generics + traits does add complexity to type signatures. E.g. consider using dynamic dispatch using trait objects trait Frobber { fn frob(&self, something: &OtherTrait); } versus static dispatch: trait Frobber { fn frob<S>(&self, something: &S) where S: OtherTrait; } Of course, static dispatch has large benefits (opportunities for inlining, possibly leading to other optimalizations). Rust adds correctness and deterministic performance (besides Rc/Arc misuse). But Rust also has the potential for 'macro/generics soup' and over-abstraction. I think it is a fair criticism of a language. Use sharp tools wisely. (Disclaimer: writing Rust daily for work.)
- qaq 9y agoWell Rocket is about as verbose as express: #[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }
- sgift 9y ago> Rust is a good language but I don't see it any time soon in the web space with that syntax and the lack of mature libraries, plus the time it takes to get anything done. Lack of mature libraries is always a problem, syntax is subjective and "time it takes go get anything done" .. which time do you measure? Time-to-first-running-example or Time-to-debugged-productions-ready-code? I have my doubts that Rust takes significantly longer for the second one.
- carlmr 9y ago>which time do you measure? Time-to-first-running-example or Time-to-debugged-productions-ready-code? Had the same experience. Rust feels slower to develop, but the type system just saves you so much headache in the long run that you're usually much faster at reaching your goal. Lack of mature libraries is a normal issue for a language that's 3 years old. It will get better with use.
- simmons 9y agoI'm personally a big advocate of Rust. That said, like yourself, I'm also a little skeptical that it's the right tool for most web apps. I think a case can be made for small Rust web apps embedded in consumer electronics that may be very resource constrained, though. (Granted, these probably aren't the sorts of apps that would be using PostgreSQL as described in the article.) I've seen a lot of great web applications written in Go that can also be quite compact (compared to Java, for instance), and I think Go might be a great candidate for the next level up in resource availability. Like many languages, the syntax becomes a lot more clear after you've used the language a while. Maybe it's me who's been warped, but I've been programming in Rust for long enough that the example you pasted looks perfectly normal. ;)
- yani 9y agoThe syntax is not that bad but there are some poor variable names that make the code more difficult to grasp. The motivation to learn a new language and the excitement during the process are huge factors that will push many people to write a web service in Rust.
- oblio 9y ago(Maybe Steve is around) Why did Rust go with the IMHO ugly closure syntax of |stuff| ? I think that stuff -> is much nicer to look at... :( Also, not presented here, but ‘ is also kind of ugly, was there no short keyword that could have been used? “life or “lt” for “lifetime”? “span”?
- Thiez 9y agoThat closure syntax has been around longer than Steve. So I take it you would like to be able to declare your references as `&life of brian`?
- oblio 9y agoHeh, who knows, maybe Python adds this feature for Python 4 :p
- steveklabnik 9y agoAs my sibling says, it was there before me. Ruby and smalltalk also use this syntax, so it’s not without precedence. As for lifetimes, that syntax is from OCaml, though they use it for something else. “life” and “lt” seem too short, “span” is overloaded. We tried to explore options but none were clearly better, so we kept what we had.
- mercurial 9y ago> As for lifetimes, that syntax is from OCaml, though they use it for something else. I hadn't noticed the similarity but it makes sense. This is the OCaml syntax for generics, eg: type 'a list_with_generic = 'a list;
- steveklabnik 9y agoYeah, it's also not as different as it sounds, as lifetimes are fundamentally generics, just of a different kind than types.
- mseepgood 9y agoRust code is 80% technicalities and only 20% actual domain.