Your opinion on this benchmark?

Hello,

I found a site that benchmarks several Web frameworks for each language.
I chose Rust from the list, confident that I'd find it in the top 1 or 2 of the ranking.
But I'm surprised to see that : Java, PHP and Javascript far outstrip the Rust frameworks.

here's the link

I left java to find better performance, and now I find it number 1 in the Req/s ranking :smiling_face_with_tear:

Can you give me your opinion?

First, if 174 kReq/s vs. 145 kReq/sec matters to you, then you already have bigger problems :slight_smile: (or bigger things to celebrate… that many requests don't come from, say, less than 10-20k non-malicious active users.)

Second, not everything you read on the internet is true. Just because you saw a benchmark doesn't mean it's universally applicable.

Third, Rust has a lot more to offer over Java than raw qps.

1 Like

@H2CO3 everyone has their own reasons for switching from one language to another, mine is mainly performance, since I'm working on a project that has to handle several million data items per second with an A.I.

I agree with you that the data on this site may be manipulated, but without getting into conspiracy theories,
they put the source code of each test here : repo

it's strange that it's so low in the rankings

The tricky thing about benchmarks is in making sure that you're measuring something comparable to the real-world situation you care about. Here, it appears that they're testing the speed of the HTTP implementation and routing with a very small routing table— The generated page is both trivial and tiny.

In practice, I suspect that these parts are negligible for a real world application; the work of actually generating the page to be returned is likely much more expensive. So, while the benchmarks aren't wrong, I'm not convinced that they reflect anything anything useful.

2 Likes

in this case, there's a 12% performance difference between Java/activeJ and Rust/actix. Whether it's http or business code, these are instructions executed by the CPU, so if the java program takes 1h to finish, the Rust program will take 1h+7min.

although I think it's more a problem of thread management, knowing that Java 17 doesn't integrate Virtual threads, (Java 19 will surely have better performance).

There's a 12% difference in this case, yes, but I'm not convinced that this case is representative of any workload that will be present in a program that takes an hour to complete.

There's also the confounding factor of the quality of implementation. HTTP is a complex beast, and there may be differences in the algorithms used or the features provided by the particular frameworks under test: Does this benchmark show that Rust is slower than Java on equivalent code, or is actix doing something meaningfully different than activeJ that costs some extra time? I have no way to tell.

2 Likes

Well, if you use a different site that also benchmarks web frameworks, you can find C++ and Rust as 1 and 2 in the ranking:

I generally find that all these benchmarks are of questionable value, especially for languages. Depending which frameworks you look at, you could say that Java is 18x faster than Rust, or that Rust is 250x faster than Rust. And I don't think that either of those is generally accurate.

Details other than language will have far more impact on how your project goes. Rust gives more control, but that doesn't always mean more speed. That control can also be misused to do things worse than languages that force a particular approach.

8 Likes

Well this random search result apparently has JavaScript come first Reddit - Dive into anything

BRB, porting everything to Just.

2 Likes

@scottmcm the benchmarks on the TechEmpower site are very old (2022-07), about ~1 year, a lot has changed since then, and it doesn't contain the recent frameworks (+ the new runtimes) that are on the top 10 that this Topic talks about.

@simonbuchan what surprises me is how interpreted or pseudo-compiled languages get so far ahead of Rust.

You can't blame 100% of Rust for this, the optimizations of web frameworks are also responsible.

Rust makes up for its complexity with its performance and security, but if easy languages start to outperform it, this could put a brake on Rust's adoption.

I like Rust a lot, and I know it has a lot of potential, it makes me sad to see it dethroned. if it's by Asm or C/C++ it's okay, but not Javascript and PHP?!!! :face_with_raised_eyebrow:

The point is more that benchmarks are only good at measuring what they measure, tautological but often forgotten, and that they normally get very different results between each other despite claiming to measure the same thing.

It's fun to see Javascript beating Rust, but it's not super meaningful in the sense of driving business decisions. A lot of the time you need to see 2x to 10x throughput performance differences (or even more!) before you can really start considering that it's relevant to making language choices, and even then it's down the list after other performance metrics like memory and 99% latency and subtler things like security and whatever you want to call "it's a nightmare to actually write code like this".

Here, sorting by 99% (64 byte) latency, for example, 10 of the top 11 frameworks are rust, and the top is an order of magnitude faster. But does that matter at all when we're talking about whether it's 1ms or 0.1ms? Who cares when the ping is 100ms? Throughput is also not hugely relevant for most services, since it's application code that's going to dominate. Sure, you can write Java code that has incredible throughput, but only by writing it like you're writing C, and the slightest mistake will silently drop you back to multiple second GC pauses every Nth request, and of course any public packages out there are completely out of the question.

Full, even if small, applications; written in idiomatic, maintainable style, are far more informative of what the "performance of the language" is, but both this is a lot of work, and now you're buying all the trouble of "no true scottsman"-ing the specific implementations: "well of course it's slow if you do that, you would do this if you really cared about performance", all the way up to JNI-ing to hard-crafted assembly.


nit:

Carefully crafted code used with advanced JITs is often competitive with native code. There's a few reasons for this, but essentially there's a pretty hard floor for how good machine code you can generate, and if you avoid triggering the GC or fall off the JIT fast paths, you're pretty much guaranteed to be running 100% JITed machine code. There's some edge cases where JIT can even beat native compilers due to having more information (vague example: this array is mostly cats, not dogs, so optimize for that).

4 Likes

@simonbuchan on the whole you're not wrong, maybe I'm too much of a perfectionist, but believe me, on some projects, those few milliseconds of latency have an enormous weight. it reminds me of a project I abandoned because of the latency "~ms", I wanted to create a streaming server (video/audio) ULL (ultra low latency) in java.

it's good to be jealous of your favorite language (Rust) :laughing: I don't like to see benchmarks that don't show all their power.

and as you said, for a web server, these few ms of differences are negligible if there's a business logic behind them. to be realistic, it's impossible for an application on a single instance to serve 150K Req/s if it has to do processing and connect to a database. :thinking:

In any case, thank you all for your opinions, it was very interesting. :pray:

I wondered the same multiple times.

If you have the chance to look at the source code of each solution / the best contenders, you will spot the differences.
Some will intentionally modulate the code so that it shine in this benchmark.
As for the PHP and other: take https://github.com/rryqszq4/ngx-php for example.

It is basically Nginx doing most of the work..

"Ballpark" / "Production ready" / "Batteries according to your needs" are the keywords you are looking for.

1 Like

Okay, and are you individually uploading each item in a separate HTTP request?

  • If yes, then stop doing that.
  • If no, then you are doing batch processing, and inference time will dominate the 1/100'000th of a second it takes for the server to route your request, so the point you are trying to benchmark for is moot.
1 Like

There's no such thing as an easy language, that's a myth.

Rust is only as complex as needed to achieve its goals (compile-time proven memory safety without GC and correctness in general), and no more. This is not true of many mainstream languages, in which the complexity is accidental rather than essential, much more of a result of historical artefacts and design errors, rather than the consequence of inherent necessity.

It is also the case that in such mainstream languages considered "easy", the lack of a clear ownership story (and strong types altogether) makes it possible to hammer out low-quality code faster. But should that really be the benchmark of our craft, should LOC/hour be what we take pride in? Or should it be instead the abilty to deliver carefully designed, correctly operating, high-performance software?

If the latter, then there will always be a place for Rust in the industry.

4 Likes

Speed aside, Java might be more memory-hungry in a lot of situations. This effectively can limit upscaling.

@H2CO3 they chose to communicate using Http/RPC in this project, as the traffic had to pass through a WAF and other subsystems. (Using direct socket communication was very complicated to set up, especially with the disconnections caused by the network switchover between 4G and 2G).

Rust is a great language that allows you to do many things while being a static language, especially when using Macros, I totally agree with you on what you say, but companies see more the TTM "time to market", ex: the birth of Go (I do not like its syntax).

@Girole I checked the code of 3 tests in this benchmark, and it seems to be correct, but I understand what you mean.

@jbe I can't contradict you on this point, Java is really bulimic.

Pretending that all code in a language is the same will lead to making bad decisions.

It's often possible to write extremely fast non-idiomatic code in many languages. That's why you'll see Haskell programs in Which programming language is fastest? (Benchmarks Game) that are coded basically the same as the C ones, even though that's not how anyone who wants to use Haskell wants to write their code.

Speed Without Wizardry (as well as the one before it, Oxidizing Source Maps with Rust and WebAssembly - Mozilla Hacks - the Web developer blog) does a good job pointing this out:

  1. He perfectly demonstrates one of the points my “Oxidizing” article was making: with Rust and WebAssembly we have reliable performance without the wizard-level shenanigans that are required to get the same performance in JavaScript.

If your team is entirely experts in the exact engine you're going to be using, then sure, you can all be very careful to stay on the JIT fast-paths.

For example, C# code can be very fast. Microsoft's rewrite of the C# compiles (GitHub - dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.) is a great example of that. But doing that means turning on the performance warnings that tell you not to use certain things -- like CA1860: Avoid using 'Enumerable.Any()' extension method - .NET | Microsoft Learn about certain uses of LINQ -- because unlike in Rust they don't optimize down to something efficient.

By the time you're doing manual buffer management in Javascript or C# -- because despite them having a GC, using it is too slow -- then I posit that you'll have a better time doing it in Rust, and make fewer mistakes, because Rust has the tools to help with getting that right. Whereas in a GC language the GC is the tool they have for getting it right, yet high-performance code tends to not be able to use it.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.