4 ms·
Rust is more similar to C++, not Swift, here. The distinction is in the programmer model involved. With Swift and GCd languages, you do not know about when the
by Manishearth 10y ago
Rust is more similar to C++, not Swift, here.
The distinction is in the programmer model involved. With Swift and GCd languages, you do not know about when the deallocations will happen, because this requires analysis of the whole program and the executions. You program with this in mind. Since GC/ARC is the only way to share, you end up using it often. The compiler can prevent some of this, but not the majority, because there isn't enough annotation helping it.
(There is this difference between Go and Java, too. Go is more explicit about sharing than Java, and needs annotations when you share things (* and &). Java does not. So while Java 8 is getting escape analysis, it can never be as good as what Go does or potentially can do because the compiler just doesn't know enough. Go also generally avoids sharing unless necessary, whereas in Java you will see things shared willy-nilly because the distinction only lies in the optimizer. These annotations aren't as fine grained as Rust -- they're at the same level as Swift, approximately, but I'm trying to give an example of the same annotation-drives-optimization-and-design thing at a different level.)
With Rust and C++, you know just by looking at a function what will be deallocated and where. C++ has API designers implement drop flags anyway (in the form of nulling the internal pointer, or something) for all types with a move constructor. The model of dealing with data changes; you explicitly think about where data comes from and how to share it. The additional annotation of zero-cost borrows (instead of just saying "Share this ... somehow", which is what Go and Swift do) means that zero-cost borrows will always be zero-cost, and not only if the optimizer decides it knows enough to be able to help.
Note that ARC is much much costlier than than pointer-sharing. Not directly because of the increments; but because dynamically allocating for every instance of sharing, and then accessing that allocation whenever you wish to do a read/write or bump the reference count; is horrible for cache performance. This can be assuaged with a tuned allocator, but is less efficient than the usually-to-the-stack borrowed references of Rust.
I will point out that Swift satisfies the academic definition of garbage collection and Rust/C++ do not, but I don't think terminology is as important as understanding what's actually going on.
Rust is "automatic", in a sense, agreed, but automatic memory management is a vague term that can mean anything.
- winstonewert 10y ago"I will point out that Swift satisfies the academic definition of garbage collection and Rust/C++ do not" What is this academic definition of garbage collection? I'm familiar with how the different models work. But I'm having trouble with a definition of garbage collection that excludes Rust while containing Swift.
- pcwalton 10y ago"Down for the Count", for example, surveys the approaches to GC in its introduction: https://users.cecs.anu.edu.au/~steveb/downloads/pdf/rc-ismm-2012.pdf https://users.cecs.anu.edu.au/~steveb/downloads/pdf/rc-ismm-... Note that reference counting has been considered a form of GC since the 1960s.
- winstonewert 10y agoThe question isn't whether reference counting is garbage collection. In the academic definition: it is. The question is whether Rust's approach which looks a lot like reference counting where most of the time the compiler knows the reference count at compile time, also qualifies as garbage collection.
- Manishearth 10y agoIt isn't, because in other languages with linear/affine types it isn't called as such. Nor is C++s unique_ptr. Or Cyclone, which has region types. Rust isn't exactly revolutionary in its core memory management ideas, these have been around for a while and have been inside other languages. Cyclone, for example, is basically Rust (memory management wise) but as a safe dialect of C and a different stance on mutation and other things. It is not considered a GCd language. Rust just puts all these ideas together nicely. The compiler doesn't actually keep track of a reference count, btw. Refcounting and linear types/ownership/borrowing lead to very different programming styles. In Rust's model you actually have to think about ownership and design your program with this in mind that as much as possible you want to use single ownership. Given that they have very different impacts on programming style, they are pretty different practically speaking. On the other hand in swift you deal with memory management much like in Java, though with a few more choices you can make. Go might be a more apt comparison as far as memory management, though swift is more fine grained than Go as well.