Live data from Hacker News

Speed of Rust vs. C

kornel.ski

441–450 of 546 posts

Re: Speed of Rust vs. C

#441
post #91

> "Clever" memory use is frowned upon in Rust. In C, anything goes. No, it does not. If Rust programmers don't have discipline in C, other people have. And don't drag out some random CVE numbers again. These are about a fraction of existing C projects, many of them were started 1980-2000. It is an entirely different story if a project is started with sanitizers, Valgrind and best practices. I'm not against Rust, exce…

A tool that requires "discipline" from its users is strictly worse than a tool that doesn't.

I want to be able to write code without having to be "disciplined" about how I access memory. Means I can be more "disciplined" about business logic.

Re: Speed of Rust vs. C

#442

A graph would be good. Any graph. Preferably multiple. Otherwise, this is all empirical data. Show me why Rust wins, and how. Telling me "doubly-linked lists are slow" is not useful, as a developer considering one of these two languages.

Most things in life are subjective and cannot be reduced to graphs and other "empirical data". I learned this later in life than I should have, and since then I've spent time and effort building some of the mental circuits required to evaluate subjective experiences and arguments. Perhaps doing so may be useful to you as well.

Re: Speed of Rust vs. C

#443
post #439
post #435

Earlier quoted context omitted.

This style of memory management can be as pervasive as you like! You are reading way more detail out of people's comments than they put there, and then getting upset about your misinterpretation. If every throwaway string in your program comes from an arena that you clear later, great! Rust won't stop you, or even force you to use unsafe every time you build one. The unsafe code goes in a "give me a fresh chunk of te…

Okay, but if I do this everywhere, then I de facto don't have memory safety. Why, then should I use Rust and pretend like I am getting memory safety? Why wouldn't I use a lower-friction language with a faster compiler? It looks to me like the Rust community has this weird way of wanting to have its cake, and eat it too, about memory. Y'all want to advertise how important memory safety is, how great it is to have, and…

> Okay, but if I do this everywhere, then I de facto don't have memory safety.

No, that's not how this works. You write the unsafe code in one place and make sure it's correct (just like you'd do in C or Jai), and then you wrap it in a function signature that lets the compiler apply its memory safety checks to all the places that call it (this is what Rust gives you over C).

This is still a meaningful improvement to memory safety over C. The compiler checks the majority of your program; if you still see memory bugs now you only have a small subset to think about when debugging them.

This is also not very different from a hypothetical language with your "actual" memory safety- in that case, you still have to consider the correctness of the compiler checks themselves. Rust just takes a more balanced and flexible approach here and moves some of that stuff out of the compiler. (In fact this simplifies the compiler, which increases confidence in its correctness...)

Rust has been very clear about all this from the beginning. If you are still reading people's claims about Rust memory safety a different way, that's on you.

> Why wouldn't I use a lower-friction language with a faster compiler?

That's totally up to you! I don't have a problem with people using other languages for these kinds of reasons. My goal here is not to convert you, but to cover more accurately what Rust is and isn't capable of. (At the root of this thread, that's things like "writing fast software with effective memory management styles.")

Re: Speed of Rust vs. C

#444
post #439
post #435

Earlier quoted context omitted.

This style of memory management can be as pervasive as you like! You are reading way more detail out of people's comments than they put there, and then getting upset about your misinterpretation. If every throwaway string in your program comes from an arena that you clear later, great! Rust won't stop you, or even force you to use unsafe every time you build one. The unsafe code goes in a "give me a fresh chunk of te…

Okay, but if I do this everywhere, then I de facto don't have memory safety. Why, then should I use Rust and pretend like I am getting memory safety? Why wouldn't I use a lower-friction language with a faster compiler? It looks to me like the Rust community has this weird way of wanting to have its cake, and eat it too, about memory. Y'all want to advertise how important memory safety is, how great it is to have, and…

Memory safety is not some sort of binary thing which you either have or you don't. All memory safe environments are built on a foundation of unsafe code. For example, Java being memory safe assumes the JVM or JNI code doesn't have any memory safety bugs.

What Rust does is reduce the amount of code that's memory unsafe, that needs to be triply reviewed and audited. Reduction of the scope of high-scrutiny code is the single most leveraged thing that can be done to improve code quality in a large, long-running project. Why? Because it lets you do careful, time-consuming analysis on a small part of your codebase (the bits that are marked unsafe), then scale the analysis up to the rest of your code.

> These stories are mutually inconsistent. Either you have memory safety or you don't.

This is... what can I say. This is simply incorrect. It pains me to say this as a fan of your games but you really don't seem to have any idea what you're talking about.

Re: Speed of Rust vs. C

#446
post #424

Earlier quoted context omitted.

ack might be an example. It's Perl, not Python, and its author is on record as saying that performance isn't his goal. So it's a bit of a strained one. But yes, it's true, I don't know any other serious grep clone in a language like Python. This is why I hedged everything initially by saying that I know that absence of evidence isn't evidence of absence. :-) And in particular, I framed this as, "I would learn somethi…

When I used to write in Cython + NumPy I would pre-allocate numpy arrays written into by Cython. It's C-like, but because of the gradual typing I think firmly in the high er level (for some value of "er"). One can certainly do that stuff in Nim/SBCL/etc. (and one sees it done). While allocation is pretty pervasive, I'm skeptical that everywhere or even most places you do it is an important perf bottleneck. Without a…

> While allocation is pretty pervasive, I'm skeptical that everywhere or even most places you do it is an important perf bottleneck. Without a count of these 20 times it matters and these 40 it doesn't, it's just kind guesswork from an all too often frail human memory/attention that "ignores the noise" by its very nature. You might be right. Just trying to add some color. :-)

In general I agree. But I'm saying what I'm saying because of all the times I've had to change my code to amortize allocation rather than not do it. It's just pervasive because there are all sorts of little buffers everywhere in different parts of the code. And those were put there because of experimenting that said the program benefited from them.

The key here is that the loops inside of ripgrep can grow quite large pretty quickly. There's the obvious "loop over all files," and then there's "loop over all lines" and then "loop over all matches." ripgrep has to do work in each of those loops and sometimes the work requires allocation. Even allocations at the outermost loop (looping over all files) can cause noticeable degradations in speed for some workloads.

This is why I'm so certain.

The numpy example is a good one where a substantial amount of code has been written to cater to one very specific domain. And in that domain, it's true, you can write programs that are very fast.

> So what "level" is C, the language?

Oh I see, I don't think I realized you wanted to go in this direction. I think I would just say that I absolutely agree that describing languages as "levels" is problematic. There's lots of good counter examples and what not. For example, one could say that Rust is both high level and low level and still be correct.

But like, for example, I would say that "Python is high level" is correct and "Python is low level" is probably not. But they are exceptionally general statements and I'm sure counter-examples exist. They are, after all, inherently relativistic statements, so your baseline matters.

That's kind of why I've stayed in "hand wavy" territory here. If we wanted to come down to Earth, we could, for example, replace "high level languages" in the poster's original statement with something more precise but also more verbose that this discussion still largely fits.

> I am usually told I write in much too detailed a way and a trimmer way might have higher persuasion/communication performance! { How's that for "meta"? ;-) }

Yeah, it's hard to be both pithy and precise. So usually when one is pithy, it's good to take the charitable interpretation of it. But we are technical folks, and chiming in with clarifications is to be expected.

> I don't think we'll resolve anything objective here

Most definitely. At the end of the day, I have a prior about what's possible in certain languages, and if that prior is proven wrong, then invariably, my mental model gets updated. Some priors are stronger than others. :-)

> You aren't making any strong objective claims to really rebut

Right. Or rather, my claims are rooted in my own experience. If we were going to test this, we'd probably want to build a smaller model of ripgrep in Rust, then try implementing that in various languages and see how far we can get. The problem with that is that the model has to be complex enough to model some reasonable real world usage. As you remove features from ripgrep, so to do you remove the need for different kinds of optimizations. For example, if ripgrep didn't have replacements or didn't do anything other than memory map files, then that's two sources of alloc amortization that aren't needed. So ultimately, doing this test would be expensive. And that's ignoring the quibbling folks will ultimately have about whether or not it's fair.

> I guess your other biggy is Go and that might actually not have worked of all the alternatives bandied about by pjmlp and myself so far.

I would guess Go would have a much better shot than Python. But even Go might be tricky. Someone tried to write a source code line counter in Go, put quite a bit of effort into it, and couldn't get over the GC hurdle: https://boyter.org/posts/sloc-cloc-code/ (subsequent blog posts on the topic discuss GC as well).

Re: Speed of Rust vs. C

#447
post #385

Earlier quoted context omitted.

Yes, writing distributed systems since 1999. What was done in C, C++ and Tcl, I nowadays use Java and .NET languages. If we really need something low level that either Java or .NET cannot offer, a native library for a specific component will do, no need to throw the whole thing away and do one of those rewrite blog posts.

Tail latency due to memory pressure tends to be inherent to the nature of garbage collected languages with mutable state. This is not an issue if you have more RAM then the system needs, but often RAM is extremely scarce.

Garbage collected languages also offer means to do C like memory allocation, it is matter to use the language features and FFI capabilities, but many just learn their stacks superficially and follow Rewrite in X trendy blog posts instead.

Re: Speed of Rust vs. C

#448
post #177

Earlier quoted context omitted.

Parallelization is the nuclear energy of comp science. Loads of potential, high risk reward and they would have gotten away with it, if it were not for those meddling humans. Its non-trivial and can only be handled by accomplished engineers. Thus it is not used - or is encapsulated, out of sight, out of reach of meddling hands. (CPU Microcode shovelling non-connected work to pipelines comes to mind / NN-Net training…

> [...] or is encapsulated, out of sight, out of reach of meddling hands. That's the real issue here! Most language have poor abstractions for parallelism and concurrency. (Many languages don't even differentiate between the two.) Encapsulating and abstracting is how we make things usable. Eg letting people roll hash tables by themselves every time they want to use one, would lead to people shooting themselves in the…

> Exactly because they move all the fiddly bits out of the reach of meddling hands.

You don't even need to hide those out of reach. You just need to make it dead simple to use and pretty much nobody will want to touch the fiddly bits.

And those who do know they had it coming.

Re: Speed of Rust vs. C

#449
post #447

Earlier quoted context omitted.

Tail latency due to memory pressure tends to be inherent to the nature of garbage collected languages with mutable state. This is not an issue if you have more RAM then the system needs, but often RAM is extremely scarce.

Garbage collected languages also offer means to do C like memory allocation, it is matter to use the language features and FFI capabilities, but many just learn their stacks superficially and follow Rewrite in X trendy blog posts instead.

There is a very big difference between what particular environments offer in theory (yes, you can write object pools in Java and many high-performance projects use them) and the situation in practice (there are people who spend a large chunk of their professional careers doing JVM tuning).

Idiomatic Rust avoids the situations which require JVM tuning experts. You can write a Rust service, put it into production and tail latency is very likely not going to be a problem at all.

Now you may decide that needing the occasional services of a JVM tuning expert is better overall than ownership concerns being pervasive throughout a codebase, depending on the specifics. But do accept that the trade-off exists.

Re: Speed of Rust vs. C

#450
post #271

Earlier quoted context omitted.

I don’t get this obsession with “dangerous.” Honestly, what does that even mean? I think a better word is “error-prone.” Danger is more like, “oh my god a crocodile!”

Concurrency bugs can absolutely cause dangerous danger of the deadly variety: https://en.m.wikipedia.org/wiki/Therac-25

Unfortunately, as is most always the case of negligence instead of some particular language features:

“A commission attributed the primary cause to general poor software design and development practices rather than single-out specific coding errors. In particular, the software was designed so that it was realistically impossible to test it in a clean automated way.“

Ergo, concurrency doesn’t kill people, people do.

Post reply on HN