Live data from Hacker News

Rust vs C Pitfalls

garin.io

321–330 of 379 posts

Re: Rust vs C Pitfalls

#321
post #32

Earlier quoted context omitted.

To me it's almost the opposite. I like C a lot, but I ended up compromising on C++11 because in some programs I need more features to keep the implementation clean. I pay the cost of a messy language (C++) when implementing my libraries in order to have simpler applications that use those libraries. I've written C-like programs in Rust, and that goes very well. But I really like function overloading, generic operator…

> Rust had the chance to make strings feel as comfortable as integers, but instead they introduced their own dichotomy with String and &str. It makes perfect sense when you understand the differences and reasoning behind it. A `String` is a heap-allocated string that can grow in size. On the other hand, a `str` is basically a fixed-size string array, but you'll never interact directly with this type because there's n…

No, the default integer is u32. If type inference can't provide a better type, Rust will pick u32. If type inference can pick a better type it will use it. So if you create an unsuffixed int literal and use it for indexing, that literal will be a usize.

Rust will type error if you try to use u32s with an array so it's all good though. Just means that you need to specifically `: usize` things.

If you need an integer type for counting stuff, u32 is fine. If you actually need to talk about memory, use usize. The compiler will force you to do it.

Re: Rust vs C Pitfalls

#322
post #308

You're so wrong that is laughably. That laughably hashing functions are highly specialized implementations for a proposed problem. There is NO MORAL there. I code C for living and if we can use "laughably hashing functions" to gain performance we WILL DO.

> You're so wrong that is laughably.

This comment breaks the HN guidelines by being uncivil. Please express your point substantively. If someone else is wrong, show them (and the rest of us readers) how. Then we all learn something. Also, please don't use uppercase for emphasis—that's in the site guidelines too.

https://news.ycombinator.com/newsguidelines.html

We detached this comment from https://news.ycombinator.com/item?id=13269145 and marked it off-topic.

Re: Rust vs C Pitfalls

#323
post #316

Earlier quoted context omitted.

Rust can do custom hashes as well, to be clear. There's been some arguments over what hashes are allowed in the game in the past.

To be clear: anyone can contribute a Rust k-nucleotide program that uses a custom hash function, just like those used by other programming languages.

Wasn't there some issues around a "custom library" for this? I distinctly remember there being some kind of argument about what is legal and what isn't.

That is, I think I'm thinking of this:

> k-nucleotide will explicitly require built-in / library HashMap.

https://alioth.debian.org/tracker/?func=detail&group_id=1008...

Since C doesn't have a standard library hashmap, you can write an entirely custom one just for the benchmark. But since Rust has a built-in hashmap in the standard library, you cannot. Even though you could write Rust code that's the same as the custom C hashmap.

Re: Rust vs C Pitfalls

#324

Earlier quoted context omitted.

I see a lot of folks talking about this, but I live in a Rust bubble. From my POV a lot of the folks using Rust use it for primary reasons other than memory safety; many could afford to use python or something and get away with it. I suspect there are fewer blog posts about this, however. I'll take a shot at some of the advantages: Algebraic datatypes : Seriously. These are amazing. C++ has them with Boost's variant…

Thank you, this is exactly the sort of comment I was hoping to inspire, and it gave me some food for thought. On first glance, I can see some utility in the ADT matching, but not necessarily something I miss in C++ (std::variant + templates gets me most of the way, although there are some issues with that approach). On the other hand, the clean separation of concerns and clear syntax of the traits example looks very…

Yeah, my point about std::variant is that it doesn't get used pervasively. With a few standardized macros for pattern matching we could get someplace, but right now, like with most new C++ features, codebases and libraries are very selective about the ones they use. This means that your natural C++ "style" can't rely on them, and not all libraries are written with the pattern in mind. OTOH in Rust everything is designed using enums, and any Rust code I write will be free to use enums. It works out quite nicely. In Rust it's not a tool you sometimes might reach for, it's a tool you reach for a lot, because most data is an "or" type.

Re: Rust vs C Pitfalls

#325
post #18

Earlier quoted context omitted.

Do you think we'll see major games having significant engine components being written in Rust?

I don't work in that field, but I doubt game programmers will be early adopters of rust, as I think they mostly don't care about memory safety.

There's been some interest, but I think the likes of jblows Jai language that emphasize rapid development and programmer convenience over correctness will likely catch on faster.

Re: Rust vs C Pitfalls

#326

Earlier quoted context omitted.

What are you talking about? I don't get people making these posts without any detail whatsoever as to what they're talking about. I have a fully static binary that includes futures, nix, tokio, uuid, and more. Even statically compiled with Muslims it's less than three megs. And if I didn't use the nix package for a setsockopt call, it would be perfectly capable of running on Windows (and I could easily make it cross…

There are more systems than POSIX and Windows. Also, even in popular Linux systems Rust is not even installable in a straightforward way (e.g. Ubuntu 15.10, my system), so go figure. Regarding Rust bloat, I don't know if has got any better recently, but it was crazy bloated in comparison to C.

The bloat issues are (a) a constant overhead and (b) a matter of defaults.

See https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...

Rust statically links to libstd by default because it's not there as a dynamic lib on most platforms. On top of that, it links in jemalloc. This makes small Rust binaries look larger than they need to be. The overhead dwindles as you start looking at larger Rust programs. If you actually need to get rid of that overhead, the option is there, it's just not default.

Addition to popular package managers is being worked on.

Re: Rust vs C Pitfalls

#327
post #237

Earlier quoted context omitted.

> That's not saying that borrow checker is worthless but it does add overhead It's important to emphasize out that this is compile time overhead, not run-time overhead.

It adds runtime overhead by forcing the programmer to work around the single-ownership rules, via runtime checking (Arc, etc) and more expensive interfaces. For example, consider a simple thread-local counter. In C this would be e.g. an object in the tdata section, accessible via thread-local addressing. But in Rust, you have to use something like RefCell, which requires runtime tracking of mutable borrows. So Rust's…

You only need a Cell for a counter (not even an atomic). Cell has no overhead over C -- Cell turns off some optimizations that exist in Rust to give you a C-like type.

I've been programming in Rust and C++ codebases for a while now. In general I find that Rust lets you dance close to the line of unsafety without worrying, resorting to Arc/RefCell only when you have to. In contrast, most C++ codebases I have worked with make use of shared_ptr (or its equivalent) quite often, because the language doesn't give you the tools to thread scoped borrows safely through a chain of functions and have it stay safe in the face of future code changes.

Re: Rust vs C Pitfalls

#328

Author forgets some inconvenients of Rust: massive bloat, multi-platform issues, etc.

What are you talking about? I don't get people making these posts without any detail whatsoever as to what they're talking about. I have a fully static binary that includes futures, nix, tokio, uuid, and more. Even statically compiled with Muslims it's less than three megs. And if I didn't use the nix package for a setsockopt call, it would be perfectly capable of running on Windows (and I could easily make it cross…

(er, "Muslims" was auto-corrected from 'musl' and I didn't catch it until now, sorry)

Re: Rust vs C Pitfalls

#329

Earlier quoted context omitted.

I don't know if you noticed but we are discussing naive solutions which I've mentioned couple of times in previous posts. Code you linked is not naive solution. Things you proposed to do are not naive either.

Here's the thing; it is a naive solution. You may not want to accept it because that contradicts your claim of the Go solution being faster, but at that point it becomes a he-said/she-said kind of scenario because I can claim that your Go solution isn't naive as well and have exactly the same "validity" for such a claim as you do.

Anyway this really doesn't matter as his solution is the slowest of all which confirms what I wrote and contradicts what he wrote.

For me it's not naive solution. Do you have any proof it is? Can you mathematically prove that it's naive solution? I know I can't. For everyone naive solution is something different, what I saw in burntsushi reply and what I wrote myself is the closest to what I think are naive solutions.

> like enabling LTO, setting O3, disabling jemalloc, and using the musl target.

And this is for sure not part of naive solution either.

> You may not want to accept it because that contradicts your claim of the Go solution being faster

This is not true. You can find perf numbers of his solution in my second reply to him. Or you can compare those solutions yourself.

Re: Rust vs C Pitfalls

#330

Earlier quoted context omitted.

It adds runtime overhead by forcing the programmer to work around the single-ownership rules, via runtime checking (Arc, etc) and more expensive interfaces. For example, consider a simple thread-local counter. In C this would be e.g. an object in the tdata section, accessible via thread-local addressing. But in Rust, you have to use something like RefCell, which requires runtime tracking of mutable borrows. So Rust's…

That's not actually true though. You can use an atomic with a relaxed ordering. For example: https://is.gd/M1Q3Bu Now, to be fair, this is only one example and I'm sure you could come up with a better one. But this isn't especially controversial. Rust's entire standard library is living proof that you need unsafe to do some things efficiently. The value proposition is that such things can be bundled up behind an abst…

Thread locals are thread local, so you don't need AtomicUsize, you just need a Cell, which has zero overhead.

https://is.gd/c0iCz6

Edit: Zero overhead as compared to C, that is. Cell has a slight overhead in Rust because it prevents certain optimizations that aren't the default in C.

Post reply on HN