
The relative performance of C and Rust - dmpk2k
http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performance-of-c-and-rust/
======
vnorilo
This was a well-crafted benchmark, but what I found especially interesting and
insightful was the "apples to oranges" part: C and Rust encourage distinct
approaches, different data structures. I feel it is actually more interesting
than implementing the same algorithm and comparing optimizer pipelines.

~~~
stochastic_monk
How is Rust encouraging a different data structure besides providing a btree
set and not an avl tree set?

The C stdlib does not come with an AVL tree. Why would one not implement a
b-tree in C for this comparison? It’s not as if K&R has “Use binary, not
b-trees!” on the front cover.

~~~
bjourne
The comment is wrong for C, but could be right for C++. The data structures in
STL are all implemented as red-black trees. They can't be rewritten as B-trees
because of some iterator/synchronization/backwards compatibility mess.

I once did a similar benchmark to the one in the article and found that Rust
outperformed C++ because the C++ code was using the builtin std::map. But for
reeeeeeally big datasets PostgreSQL beats them both so who cares. :p

~~~
stochastic_monk
There are STL-compatible B-tree implementations in C++, so I would still use
one of those instead of std::map. Besides, std::*map implementations are all
rather slow.

------
abenedic
As a meta comment, I really like how active Stepha(e?)n is on internet forums.
And the energy around Rust is pretty intense. I feel like in there, people are
unwilling to try to embrace some of the nuance in the arguments that some
people make against Rust.

A person should understand that no language(programming or otherwise) is
perfect. Therefore there is some criticism of any language that is valid.
Therefore some criticism should be taken seriously as there may be a real
point to the criticism.

There are many posts like this, where there are comparisons of Rust to C.
Realistically they are all a little biased towards Rust as Rust is a C++
replacement really. A more proper comparison would be Zig or D as a better C
against C.

Just understand that a person defending C is not always an idiot, and maybe
they have point. Consider the excessive memory use of any working Rust
compiler. That will probably not be remedied anytime soon and is a legitimate
complaint. The ideal of how something could be is not how something is. The
reality is that C works pretty well most of the time, Rust works well most of
the time. They both fail at some things.

~~~
vvanders
I don't think I've seen anyone claiming that Rust is a perfect language
without flaws. Heck I'd hold up all of the huge strides that have been made in
errors, usability and constant feedback as a counter example of that.

You see a lot of people holding up Rust precisely because we've been there for
the last 5/10/15/20 years. The day I don't have to write a makefile or build
yet another CMakeLists.txt is the day I rejoice.

What Rust offers is another option in the native, non-GC'd language space. A
space that has very few languages and even fewer yet that are shipped at
scale. Rusts inclusion w/ FF means that the have to address the robustness,
security, performance and usability of the language to a degree that you don't
commonly see.

Having just blown 4+ hours today dealing with the linker on a mixed C/C++
project I don't really miss a lot of the baggage that comes with native
development these days. Rust gives you the option of dropping down to that
level while still preserving a set of sane, opinionated defaults that are
pretty well thought out.

~~~
kxyvr
Since you made a mention of CMake, does Rust really provide an alternative for
building multilanguage projects? When I went to look for examples on how this
is managed, it seemed horrendous. For example, some projects manage this by
writing a program to download, unzip, and build the source:

[https://github.com/elrnv/ipopt-rs/blob/master/ipopt-
sys/buil...](https://github.com/elrnv/ipopt-rs/blob/master/ipopt-sys/build.rs)

Others just assume that the libraries are there, but they still require a
program to compile them:

[https://github.com/cmr/openblas-
src/blob/master/build.rs](https://github.com/cmr/openblas-
src/blob/master/build.rs)

As long as all of the dependencies are in Rust, things appear nice. At the
same time, unless I'm missing something, it seems like crates manages
multilanguage projects poorly. Though I have some major gripes with CMake,
I've managed multilanguage projects mostly well.

Is there a sane way outside of CMake to manage a multilanguage project with
Rust?

~~~
blakesmith
Check out Bazel: [http://bazel.build](http://bazel.build). I've been using it
a lot to build several multi lingual projects that include Java, C++, embedded
C, Javascript, CSS, and even Docker images. There are community Rust rules,
that I haven't tried yet, but am planning on investigating soon:
[https://github.com/bazelbuild/rules_rust](https://github.com/bazelbuild/rules_rust)

~~~
digitaLandscape
Is there a non-Google alternative for those of us who don’t want our builds
spied on?

------
nixpulvis
Fantastic read. Learned a few things about profiling I'm sure I'll use.

Just one tiny gripe, don't use a blue and green next to each other in graphs
if avoidable. I'm not even blue green colorblind, and I found them hard to
distinguish.

Thanks for the great read.

~~~
solipsism
Thanks for looking out for us colorblind people. But, funnily enough, there is
no "blue green colorblind", and to this person with red-green colorblindness,
the colors in the charts are incredibly easy to distinguish. Much easier that
the typical colors chosen.

~~~
mijoharas
I am not colourblind. I did find those colours difficult to distinguish next
to one another.

~~~
kbenson
Sometimes it's the display device, and even the angle viewing it on that
device.

Those colors appear quite distinct on my monitor. Others sometimes don't

------
quotemstr
This is not really a good comparison: the author acknowledges that the C and
Rust programs are using different data structures, and while he tries to vary
the problem a bit to explore that difference, it's still not a fairly matched
comparison, and the headline leaves the reader with the incorrect impression
that we're comparing similar things.

I'm not sure that comparing "Rust" and "C" performance is even meaningful. The
latter is a multi-implementation language, and in most implementations, can be
written in a way that gets the compiler to generate the same machine code that
the Rust compiler does. (Frequently, they both just go through LLVM.)

~~~
kiriakasis
The fact that the two benchmarks are using different data structure is one of
the main points of the a article. The author (in my opinion) argues that each
data structure would be an hell to use in the other language.

when comparing languages you need to include a measure of how idiomatic your
programs are.

------
stochastic_monk
This is a benchmark comparing different data structures more than different
programming languages. Of course the Rust program has fewer cache misses; this
is because it’s a b-tree, not an AVL tree.

~~~
kiriakasis
It is a benchmark comparing what type of data structure are easier to use in
the two languages.

Of course it is entirely subjective (the author argues for how that is due to
a static vs dynamic ownership model) and there is a single data point, which
is the author rewriting the code. (two is you consider when he/she swaps one
of the data structure)

~~~
saagarjha
> It is a benchmark comparing what type of data structure are easier to use in
> the two languages.

Then it's not a performance benchmark, it's a style and usability benchmark.

------
ridiculous_fish
What is a scenario where you would consider C and also Rust? If Rust is in the
mix, wouldn't you opt for C++ before C?

~~~
lewisinc
C++ inheritance doesn't map well to Rust's trait system for one. I think this
is an ongoing issue within the `bindgen` community, but I don't know much
beyond that. Suffice to say, some concepts in C++ do not map well to Rust and
so FFI can be hairy in some instances.

On instance of this becoming a complication would be in the GTK+ world with
the Rust bindings to GObject. There's some really good articles about their
adventures in that realm you could find.

------
saagarjha
This comparison is disingenuous. They’re using a completely different data
structure and getting a slight difference in performance, and are chalking
this up to language differences. Sure, it might be harder to implement at
B-Tree in C than it is in Rust. But then you can just use C++? Don’t make an
apples to oranges comparison.

~~~
topspin
> [They] are chalking this up to language differences

That didn't happen. The data structure difference is discussed and the
possibility of the performance difference being down to this is clearly
acknowledged. Also discussed is the _reason_ for the different data
structures, which is actually the most important take-away.

~~~
saagarjha
> Also discussed is the reason for the different data structures, which is
> actually the most important take-away.

I agree; this would have been a great stand-alone piece had it focused on this
instead of performance.

------
stewbrew
Isn't that to some extent also a benchmark of gcc vs llvm?

------
toolslive
Could the lumpiness be caused by the overflow and subsequent split of the root
of the BTree (which cascades all the way down)?

------
FartyMcFarter
Did I read the article correctly that the C code was compiled with -O2 and not
-O3? Why?

~~~
bowyakka
cargo --release doe not compile at -O3 either it's at -O2

~~~
steveklabnik
I believe that’s wrong.

cargo build —release —verbose would tell you for sure; I’m not at a computer
right now.

------
dpc_pw
TL;DR: Using dtrace to analyze the performance of AVL Trees in C vs
BTreeMaps&HashMaps in Rust. Spoilers: Rust wins every time, and you should
rewrite your software in Rust anyway ;).

~~~
nostrademons
Note that the data structure is different: AVL trees vs. BTrees. The
interesting part for me was that because of modern cache hierarchies, BTrees
appear to be superior than AVL trees even for in-memory data structures, while
before I'd thought of them as a special-purpose on-disk data structure for
databases.

~~~
klodolph
AVL trees were more competitive when memory was more shallow. These days an L1
cache hit is dirt cheap and a RAM fetch is ~200x as expensive, following a
pointer creates a data dependency. B-trees give you more L1 cache hits and
fewer pointers to follow. Back in the 1990s the cache hits and RAM fetches
were much closer to parity and there weren't as many pipeline stages to fill
so data dependencies weren't as important. Go back even farther and you have
completely uniform memory that could be accessed in a fixed number of cycles
no matter what the address.

There are a lot of good books from these eras, and there are a lot of good
books that teach with the uniform memory model. Most algorithms classes don't
talk about the hierarchy at all (even though it distorts the true asymptotic
runtime of many algorithms).

~~~
ctchocula
Agreed. It blew my mind to learn that tiling matrix multiplication is more
efficient than untiled, but that you can only show tiled is faster in a
hierarchical memory model (for tiled, you have arithmetic intensity that
scales with size of your fast memory rather than a fixed constant). Yet in
uniform memory model both are O(n^3).

------
UncleEntity
> The C version was compiled with GCC 7.3.0 with -O2 level optimizations; the
> Rust version was compiled with 1.29.0 with --release.

Isn't rust based on LLVM?

It would make more sense, for a true apples to apples comparison, to use clang
instead of GCC.

Not that I'm pro-C or anti-rust or anything but the beginning of the article
goes on about previous tests not being fair.

~~~
kiriakasis
It also insist on how this data is unfair and only relevant to the system
(comprehensive of OS, compilers, programmer skill/talent/interest/errors and
so on)

At the end the author never states that one is faster (yes, the title is
misleading, but it is then clearly clarified in the text) the main part is the
discussion about intrusive data structures.

