13 ms·
When you've worked with languages with a garbage collector, having to worry about memory management and all that jazz seems a step backwards just to save a few
by markque 11y ago
When you've worked with languages with a garbage collector, having to worry about memory management and all that jazz seems a step backwards just to save a few cycles. You want to be focusing on the domain problem not the machine. (This is directed at people who use Rust as a general purpose lang, im sure it's good for low level systems programming).
- amelius 11y agoIt would be nice if the language itself provided hooks (or whatever you would call it) to implement your own GC (or, of course, to use a library for that purpose). I have not yet encountered such a language, though (LLVM has a low-level language that allows it, but I don't know the details).
- viraptor 11y agoRust does that. Rc type is implemented in Rust. (https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html) There's also arena allocation available as a library. (https://crates.io/crates/typed-arena/ https://crates.io/crates/typed-arena/) You can add your own memory management abstractions as libraries.
- amelius 11y agoVery interesting. I'm also interested in one particular kind of memory abstraction: abstracted access to memory mapped files. Here the problem is that the base address of the memory mapped area might change whenever you perform the mapping. And you would like to use standard data-structures (like maps, lists, etc.) inside the memory mapped area.
- viraptor 11y agoMmaped files are already available it seems (https://crates.io/crates/mmap/ https://crates.io/crates/mmap/), although I've never tried it. You'd have to implement the interesting structures on top of that yourself however.
- amelius 11y agoHmm, it seems this library only provides the basic I/O. The main problem is not opening the mmapped file. The problem is having a kind of pointer that allows arbitrary offsetting, and using this pointer inside standard data structures.
- fpoling 11y agoRust has typesafe arenas, when one allocates small objects from a bigger chunk of memory and typesystem ensures that small objects do not outlive the chunk. I suppose mmap files could be treated similarly when assembling a pointer from an offset stored in the mmaped file is treated as an allocation.
- vardump 11y agoRelative pointers are great in memory map data structures. All pointers are relative to current offset. That way it's almost always also possible to get away with just 32-bit pointers -- you get +- 8 GB range. A library that can do that in Rust would be great.
- agrover 11y agoA signed 32 bit "offset" value gives you 2GB in each direction, not 4GB in each direction.
- vardump 11y agoOnly if you use byte aligned relative pointers. For data structures you don't need better than 32-bit aligned pointers. So you get +- 8GB relative offsets. It's not all that unreasonable to use 64-bit or even 128-bit alignment, for +-16 GB and +-32 GB respectively.
- Cyph0n 11y agoNim allows you to disable the GC if I'm not mistaken. D also, but to a lesser extent. Jai [1], Jonathan Blow's language in progress, has a ton of customizable features. For example, the memory allocator is quite straightforward to swap natively without any hacks. [1]: https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md
- bjz_ 11y agopnkfelix (from Mozilla) has been doing lots of investigation into custom allocators[0], custom GCs, and embedding Rust into places where a GC is already active. He also recently published some blog posts outlining the problem of GC interop[1][2]. Quoting aturon[3]: > To be clear, a major goal of this project -- outlined in the earlier blog posts -- is "GC as Interoperation Feature". That is, we want to embed Rust code into contexts with existing GCs (such as the V8 or SpiderMonkey Javascript engines), and so Felix is trying to find ways to accommodate a relatively wide range of GC approaches, with maximally safe, efficient, and ergonomic support on the Rust side. Might be a while off before good support for custom GCs for pure Rust code, but it's definitely being thought about. [0]: https://github.com/rust-lang/rfcs/pull/1398 https://github.com/rust-lang/rfcs/pull/1398 [1]: http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/ http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-spe... [2]: http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/ http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roo... [3]: https://www.reddit.com/r/rust/comments/3zqtoc/gc_and_rust_part_2_the_roots_of_the_problem/cyp0gfu https://www.reddit.com/r/rust/comments/3zqtoc/gc_and_rust_pa...
- fiedzia 11y agoWhen you work on improving performance, memory management is your domain.
- one-more-minute 11y agoIn almost all programming use cases you'd be right, but sometimes the domain problem is the machine. If you're writing control software for a drone you want to know that you're getting use out of every cycle and that there aren't going to be any unpredictable hundred-millisecond pauses.
- markque 11y agoYou can bet your house that people will be trying to use Rust for general purpose reasons such as web apps etc.
- viraptor 11y agoI already did, and it works pretty well. You spend more time developing, but the type system prevents lots of silly runtime mistakes. (which you'd spend time debugging later on otherwise) I wrote web apps in dynamic languages like everyone else and know that there are situations where you practically just ignore many potential failures and cannot be sure your code runs in practice, even with ~100% coverage. Writing in a language with proper types helps a lot. Being forced to acknowledge every error returned is great. The only time I had to think about memory management was during integration of database connection pooling and the web framework, but that's just because I was one of the first ones to try. Otherwise memory management doesn't get in the way at all.
- Hytosys 11y agoReporting for roll call. Once you get cope with abandoning all of the metaprogramming-heavy APIs a la ActiveRecord that have been front and center in pop web dev, it's quite lovely. The only thing that seems to slow down my work is the lack of a developed web ecosystem for Rust. My hypothesis was that the type system is be able to benefit practically all domains. Personally, so far, I've become a cautious believer.
- AndrewDucker 11y agoDepends very-much at what level you're working. I love C#, and I love not having to write code that worries about memory (99.9% of the time anyway). But if I was writing the .Net Runtime then I wouldn't be writing that in C#, because the runtime _does_ have to manage its own memory - and Rust looks like a very good language for writing that kind of thing in.
- markque 11y agoHow many people need to implement a lang runtime?, less than 0.0001% of all devs I would imagine. They can use C or C++ which has done the job for decades.
- fiedzia 11y agoYou can thank C/C++ for vast majority of software bugs. Billions of dollars and decades of productivity setback, and prognosis of fixing those issues for many years to come. All languages and tools that rely on people not making mistakes must die, the sooner the better.
- lionize 11y agoI disagree, all languages have the potential to be misused by poor programmers and it's the developer who is the source of the bug, the Linux kernel is written in C and is the most successful/widely used piece of software ever written largely due to the quality of the devs. Blaming a language for bugs or hoping new shiny one will stop a poor programmer for producing bugs is wishful thinking
- fiedzia 11y ago> I disagree, all languages have the potential to be misused by poor programmers and it's the developer who is the source of the bug. We can easily fix tools and processes, we will never fix people. Sure, all languages allow to create bugs, but some orders of magnitude more then others. > kernel is written in C and is the most successful/widely used piece of software end every release finds bugs in filesystem drivers, and buffer overflows and security issues and breaks display drivers. Seriously think of all the things kernel developers could do if they didn't waste years of work on tracking invalid pointers and off-by-one errors. Over and over and over again.
- danieldk 11y agoWhen you've worked with languages with a garbage collector, having to worry about memory management It's an illusion to think that in a language with a garbage collector you do not have to worry about memory management. To give an example: take a function that takes a substring of a string. 1. If a substring function returns a string with the same underlying character array (just with different start/end indices), you may be wasting memory with very large strings of which you only care about small substrings. 2. If a substring function returns a string with an underlying character array that is a copy of the particular substring, you may waste a lot of memory when you have a lot of (partially) overlapping substrings. Moreover, the substring operation is O(n) rather than O(1). In other words, in any non-trivial application working with strings you want to know the allocation behaviour of common string operations.
- markque 11y ago99% of people use the language standard library which has solved the problem.
- danieldk 11y agoNo, that does not solve the problem. Consider this Java fragment: String someLargeString = ...; //... String interesting = someLargeString.substring(10, 20); someLargeString = null; Now assume that someLargeString is garbage-collected after the last statement. Is the backing character array of interesting 10 chars long or the size of the backing array of someLargeString? You don't know, unless you know what the implementation of String#substring does. Suppose that someLargeString's array was a couple of megabytes, you could be using 20 bytes of memory or megabytes for interesting. (Note that in the case of Java they switched from a O(1) index-based slicing to O(n) copying some time ago.)
- markque 11y agoA somewhat contrived example which may require a quick look at the API docs but in the main you can focus on solving the problem, premature optimization and all that.
- EliRivers 11y agoYet people never seem to stop demanding performance in some domains. Silly peoples.
- fsloth 11y ago"worry about memory management and all that jazz seems a step backwards just to save a few cycles" We're not getting more cycles any time soon for sequential programs. Other peoples problem constraints are not necessarily the same as yours.
- titzer 11y agoUnless you use a memory and CPU profiler every day, you probably haven't got much idea what your program is doing. There are a few domains where manual control of memory management is necessary, but those are shrinking, and GCs just keep getting better with lower and lower pause times and better and better throughput. With manual memory management (like writing your program in assembly) your program will never get faster due to industry-wide advancement in GC and compiler technology. Most GC problems can be pinpointed to poor application behavior and many are due to bottlenecks in GC (e.g. too much work done in sequential phases, etc).
- vvanders 11y agoGCs are not the problem with performance. If you want real performance you need to drop down to memory layout to avoid cache misses and that means explicit control of memory allocation. I'm talking 10-50x performance increases here. Unfortunately managed languages(and GCs in particular with everything being a ref) make this much harder than it should be.
- pkolaczk 11y agoMost of the cache-related optimizations available in C++/Rust can be done as well in fast managed environments. I agree that sometimes they make it much harder than it should be, but it is often still easier to fight with a managed runtime for the 5% of performance critical code, than to fight with manual memory management of an unmanaged environment for the 95% of non-performance-critical code. If you see a 50x performance disadvantage of some program in a managed environment like JVM or .NET, it is a fault of a programmer, not the runtime nor tools.
- threeseed 11y agoIf you are writing high performance apps then you do still need to worry about the garbage collector. For example look at the huge amount of work Spark did (Project Tungsten) in order to reduce memory pressure in the JVM. Likewise in high frequency trading and other low latency apps being able to tune the JVM is a highly sought after skill. Even for most normal web apps a full stop the world GC is a common occurrence and a deadly one.
- fpoling 11y agoAlthough Rust does not have GC and requires the programmer to manage the memory when just relining on borrow checker is not enough, the language ensure that this is safe eliminating most of the worries with manual memory management. In this settings GC is not necessary beneficial as it brings an extra unpredictable latency/pauses. All is fine when it does not affect the application, but when it becomes the problem, it is hard to fix and may require a significant rewrite or a very time-consuming tuning of GC parameters.
- lultimouomo 11y agoWhen you've worked with languages that help you think about ownership (like Rust or even modern C++), being back to languages that throw you a pointer/reference had leave you on your own to figure out what it's lifecycle is and what you can to with them is a huge step back. For me is the think that sucks most when programming in Java, for instance.
- wtetzner 11y agoJust out of curiosity, why do you care so much about the lifecycle of an object. I can see why you might want to know in the case where you're representing an external resource, e.g. an open file, but otherwise, I don't see any reason to care about it. In face, with persistent data structures, you can't know. The same is true of share (immutable) data with multiple threads. You can't know the lifetime.
- Manishearth 11y ago"You have to think about it. You don't have to worry about it." https://news.ycombinator.com/item?id=10711997 https://news.ycombinator.com/item?id=10711997
- hellofunk 11y agoConsider how enormous the computer game industry is... and nearly no professional game developer will work in a GC environment because it is indeed a problem for the user experience in high performance games. Sometimes, focusing on the machine is nearly the whole point of the focus on the domain problem.
- Gankro 11y agoWell, except for literally all the developers that use Unity, Flash, Java, and GameMaker (but I guess they aren't True Professionals?) In the space of core engine stuff, I agree.
- hellofunk 11y agoFair point. But a lot of people write their own C++ engines for their apps. This is certainly true in a lot of mobile games.
- dbaupp 11y agoRust's ownership model does more than just allow avoiding a garbage collector. It allows managing arbitrary resources more easily, so it is clear who is control of things at any point of time, e.g. if a function takes a File, who should close it (if the callee closes it, or if the caller needs to) is just a matter of documentation, while it is expressed naturally in the Rust type signature, and is hence checked by compilers. This isn't unique to Rust, e.g. it's basically the same as C++'s RAII but it is checked far more precisely by the Rust compiler: it is up to the programmer to not make a mistake in C++. http://blog.skylight.io/rust-means-never-having-to-close-a-socket/ http://blog.skylight.io/rust-means-never-having-to-close-a-s... It is also an important part about getting guarantees for concurrent code, as it allows fairly precise control over sharing (or not). This not only means Rust code without `unsafe` is free from data races, but also means that, for example, one can be sure a program built on message passing (ala CSP/Go) is not accidentally sharing things that shouldn't be shared. http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.ht...