[Discuss] Port Scanning

Kent Borg kentborg at borg.org
Tue Aug 6 19:31:29 EDT 2024


On 8/6/24 14:53, markw at mohawksoft.com wrote:
> I call BS on that whole paragraph. Rust is OK, but ANYTHING you can write
> in Rust can be written to be faster in C/C++.

Both are compiled languages, frequently using related compilers. Both 
are going to approach as-fast-as-possible. Theoretically.

The practical is going to be different.


Practical case 1: Rust's advantage.

There are various reports of programmers with years old, very familiar, 
finely optimized C/C++ programs, deciding to rewrite in Rust, sometimes 
as a first Rust project, and having the naïve Rust program be 
significantly faster than the mature C/C++. In digging a little these 
all seem to be due to Rust "std" library having some very well written 
data structures that are both very fast and, because of the way Rust 
does generics, very easy to use with the data that are sitting around 
the old C program.

There is no reason these fast std data structures could not be written 
in C/C++, and be as fast, but Rust has a practical advantage here, at 
least some of the time.

A freaky thing about Rust libraries is it is common for the exact same 
"crate" (as Rust calls libraries) to be maybe used in a tiny embedded 
machine with no OS, inside an OS kernel, in some big container in the 
cloud, inside a "smartphone", in browsers via WASM, or running on the 
zillion CPUs of some some gigantic cluster that we call a 
"supercomputer" these days.

Not just core stuff, as C/C++ programmers do with something like 
strncpy() in glibc, but maybe an obscure open source crate created by 
some programmer in Nebraska, it doesn't have to be in std. (In fact the 
tiny embedded is likely "no_std".)


Practical case 2: Rust's Advantage.

Moore's Law has been sputtering and clawing and *barely* wheezing along 
for years now. Computers have gotten faster by doing more and more 
cacheing, and by having more CPUs. For multiple CPUs, with view to 
shared RAM (clever cacheing), multi-threaded programs can be screaming fast.

It is handy that writing a multi-threaded program in C/C++ is easy. The 
catch is that maintaining a multi-threaded program in C/C++ is…kinda 
impossible. Too much of a multi-threaded "program" is in the comments, 
explaining key relationships to the next programmer (or same programmer, 
if the programmer and project both survive long enough).

So multi-threaded programming needs to be approached carefully, and with 
discipline to not do dangerous things that might start out okay but will 
inevitably turn into  bugs——nasty, subtle bugs. At least for C/C++.

Rust is different. For beginners Rust is can be annoying, as the 
compiler insists on lots of extra detail that isn't needed in a C/C++ 
program. But all that extra detail *is* also in the C/C++ program, but 
it is just in the comments. For the programmer to maintain and obey.

Because Rust insists the programmer tell the compiler these things, the 
compiler will help out and prevent a range of bugs. They simply won't be 
there. This doesn't make Rust faster, per se, but it can allow Rust 
programmers to be much more aggressive about how they use multi-tasking, 
to do things that would be reckless in C/C++. And in that can be 
significant speed.


Practical case 3: C/C++'s advantage.

C/C++ compilers are more mature, so there are better optimizers for 
C/C++ programmers. This is an advantage for C. Though, not always: 
sometimes the machine code will simply be as fast as it possible, and 
sometimes Rust will be that fast, making it a wash. But on average, at 
least for the moment, C/C++ has the advantage.


Future Case

I don't hear others talking about this, and I might be wrong (would 
anyone here expect me to ever be wrong??), but because the Rust compiler 
has more information about the program than does the C/C++ compiler, and 
because it compiles both the "program" and the libraries, I expect the 
Rust compiler should be able, in the future, to optimize on a larger 
scalem and get better results. But I might be wrong. (Me‽‽)


A Why: "Zero Cost Abstractions".

Rust has lots of cool features that one would expect in, say, Python. 
And Python is a pig. Fat and slow. And though you might expect those 
features to make Rust slower, you would be wrong.

Rust is a strongly typed, compiled language. It has a compiler that is 
picky as hell (though also helpful in its complaints). They push this to 
the extreme. All of these features that seem like they would be slow are 
implemented at compile time. By the time the machine code is emitted, 
there is no speed penalty. Rust is obsessed about this.

If you can get Rust to do the array index computation (iterators and the 
like), it trusts its own index math, there will be no runtime checks to 
slow down array access, yet the result is still safe array access, as if 
there were runtime checks.

Yes, there are ways to slow down a Rust program. If you have to do some 
chaotic array accessing there might not be a way to get Rust to do that 
for you, in which case you can choose to have those accesses have a 
runtime check, and that will take a little speed. Or, you could decide 
to do unchecked array access (the "unsafe {}" feature is useful). Or, 
maybe be a little more clean, figure out how to put your index 
computation in as clean a little package as possible, prove it up and 
down that it is correct, and kind of simulate Rust's trust of its own 
index calculations.

Similarly, there is no speed penalty of doing runtime dispatch unless 
the programmer decides to do so. Maybe there are code size 
considerations, and runtime dispatch can be smaller, maybe some key 
stuff decides to fit in a small cache that way and the result is faster 
even with the extra indirection. Cool. But the programmer chooses. 
Aren't vtables part of C++? Okay, same idea, it costs a little, not a 
lot. Nice to be able to choose. That is the level Rust is at, they sweat 
runtime dispatch and avoid it by default.

Rust is that way all along. Every feature is designed to be as fast as 
is theoretically possible, the price for those fancy features is paid at 
compile time, not runtime. Zero cost abstractions.


-kb, the Kent who calls BS.


More information about the Discuss mailing list