4 ms·
In some ways Rust is in the worst possible position in terms of language design when it comes to fragmentation. In a completely manually managed language like
by munificent 4y ago
In some ways Rust is in the worst possible position in terms of language design when it comes to fragmentation.
In a completely manually managed language like C or C++, you can handle fragmentation problems yourself by writing your own allocators or doing object pools to reuse previously allocated memory. You have control over fragmentation.
In a garbage collected language like Java or C#, the runtime is able to move objects around in memory and update their pointers. So, as long as your language has a sufficiently advanced implementation, it may defragment on the fly for you.
But Rust is sort of stuck in the middle. It's safe enough that it's hard to write your own allocators or easily reuse previously allocated memory. But it's low level enough that the runtime doesn't have the freedom to move things around in memory under the program.
It's a hard problem.
- solomatov 4y ago>In a completely manually managed language like C or C++, you can handle fragmentation problems yourself by writing your own allocators or doing object pools to reuse previously allocated memory. You have control over fragmentation. It's done constantly in Rust. Create a vector of items you want to allocate. Reference to them by their id, i.e. int representing them. There're libraries supporting this style of development, for example, slab: https://crates.io/crates/slab https://crates.io/crates/slab
- mr_00ff00 4y agoI assume there might be performance issues using a vector that’s gonna reallocate when capacity is full? That being said vectors seem like a gift in rust. I feel like it’s the easiest way to get around some ownership rules when you need to work with many pointers. You can just use indices.
- cozzyd 4y agoYou can just allocate a large buffer and serialize/deserialize everything at various indices in that buffer
- sgeisenh 4y agoDoesn't the normal approach in C++ run into similar issues? The workarounds in C++ are more ergonomic than in Rust, but can still require a lot of refactoring. One of the performance bottlenecks that I ran into while reimplementing clox in C++ was using `new` and `delete` instead of `realloc` for arrays and hash tables. By the time that I figured out it was an issue, I was already using `operator new` to track heap allocations for the garbage collector.
- robot_no_421 4y agoIt's not really that hard of a problem. You just use a different allocator (like the author did in this article). In fact, you can even write your own allocator with unsafe if you want (jemalloc is already using a lot of unsafe in the code anyway, you need to use it to build any real allocator). 'unsafe' doesn't equal 'don't use'. I'll admit that unsafe Rust has a lot of rough and unergonomic features compared to C, but it's conceptually and algorithmically just as easy (or hard) in Rust to build an allocator as it is in C and C++. You also still get the help of the borrow checker in unsafe rust, so there are even some advantages.
- josephg 4y agoI hear what you're saying, and I think I agree - I just frame it slightly differently. As others have mentioned, you can use custom allocators & object pooling in rust. I'm a big fan of bumpalo. But its awkward. I think this awkwardness comes because rust is trying to straddle the gap between being a low level systems language and a high level language for application developers. In a systems language, I want full control over the allocator for each allocation my program does. Do I want to use the system allocator, or an arena or an object pool? Different tasks call for different tools. I really like Zig's approach here where every collection type which allocates takes an allocator as a parameter when the object is created. Rust's borrow checker can be super helpful here in making all of this stuff correct. But application developers don't want to think about allocators and memory fragmentation. Adding allocator traits to everything will add yet more things to learn in rust. And rust's standard library doesn't support that (yet). The result is that allocation crates like bumpalo need to ship with & maintain their own copy of the standard library's collection types. Its kind of a mess. This might eventually be fixed, but at the rate rust's development has been going lately, I suspect it'll take years for something to land on stable. But people in the community are talking about it, at least. Eg this article from the rust subreddit: https://nical.github.io/posts/rust-custom-allocators.html https://nical.github.io/posts/rust-custom-allocators.html
- api 4y agoRust lets you specify your own allocator. You can also swap it deeper down as this article describes. It’s no worse than C or C++. Also unsafe Rust is a thing and exists precisely to enable programming at the extremely low level when abstractions tend to leak badly. It’s considered bad form to have it in web apps and other normal code but seeing it in a low level data structure or an allocator would not be unusual. Managed languages and high level languages definitely do have an advantage here.