Hacker News new | ask | show | jobs
by tialaramex 1173 days ago
I mean, that's probably true in some broad categorical sense, for the question of "speed of execution of final program" which it's not clear your parent meant.

However it's not true in the specifics, there are so often little tweaks Rust has that otherwise comparable languages don't have that squeeze out a little better performance and this adds up. For example:

C++ std::vector is a perfectly respectable growable array type right? But no less than Bjarne Stroustrup observes that actually, to his apparent surprise, the reserve() method on this type isn't very effective in using what a programmer knows about the growth of a particular instance for improving upon the amortized exponential growth curve. Rust's Vec is superficially the same type. But it has a subtly different API and in the process it unlocks what Bjarne missed, using Vec::reserve() does allow programmers to successfully guide the growth curve and benefit. [[If you need the equivalent of the C++ API, Rust provides Vec::reserve_exact() for you, but you probably don't]]

Still, for a lot of us there are more important "speeds" than the performance of running code. Rust does a lot of "shift left" on errors, where more of the defects in your first attempt to solve the problem are compiler errors, which you notice quickly and can fix, rather than them failing tests, being spotted in review, or worst of all, getting all the way to an actual user where they cause real problems.

One speed that Rust doesn't have on its side is compilation performance. Rust is not going to be the fastest language for turning correct high level code into running binaries.

2 comments

> One speed that Rust doesn't have on its side is compilation performance.

I noticed that `cargo check` alone is plenty fast, and when you give it a program with a type issue to check, it reports errors nearly instantaneously (< 0.5s).

So this is probably not all the type checking (including borrowchecking) that slows things down, but the phases that happen later, likely code generation. Which leads me to a question - why is code generation so slow even in debug mode compared to other compiled languages? (this is one thing that Golang does right).

Well I guess we can always play micro-benchmarks game if you want to go down that path, including selecting specific compiler toolchains and flags while making it a point that it is a property of language XYZ, to make it even better.
I don't see the std::vector example as a micro-benchmark, we're not talking about wasting a few microseconds in a contrived example, we're talking about destroying the amortized constant time growth performance of the data structure because of an API goof.
Which std::vector, from which C++ compiler, targeting what OS, with what set of compiler flags, and optimization passes?
You'd think right?

Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.

There really are two distinct features and C++ specifies a single API call.

Yes, it only matters that it fulfills the algorithm requirements described in ISO C++, how the implementation look like is another matter.

Still, this is going way down into the weeds and very far away that any mature AOT compiled language offers good enough speed, ignoring toy compilers done by students.

You'd think right?

Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.

There really are two distinct features and C++ specifies a single API call.