Hacker News
points by vatsachak 11 hours ago | 0 comments
I think that people hyperoptimize for no reason though. How many applications are there that require no GC? I feel like you can write the no-gc code in Rust and then just use it from the C ABI from any GC language.
[–] ted_dunning 9 hours ago
Embedded systems benefit substantially from decreased GC, especially in the context of non-relocating collectors (as with Go) in machines without memory management units. The problem is not the overhead, it is the effect of memory fragmentation.

The OP article here is nice because it allows selective enforcement of allocation free code. If you have code that has some discipline about heap allocation such as having all small allocations then you are OK on the fragmentation front.

[–] bootsmann 9 hours ago
Isn’t writing Go for embedded systems kinda like eating soup with a fork tho? This language was designed to write multithreaded asynchronous code to power microservice meshes.
[–] Groxx 7 hours ago
If it's within like 90% of your targets and it's a far easier development experience, but you need to optimize a small bit to fit in the budget, tools like this can be fantastically useful. Rewriting the whole thing in, like, C, complete with a coroutine stack, would be a hell of a lot more work than "avoid allocations here".
[–] pjmlp 9 hours ago
Real time Java is doing just fine with PTC and Aicas still in business.
[–] fpoling 6 hours ago
GC in Java is the best in world with a lot options and knobs that allows to tune to particular application requirements. Still some trading platforms using it disable GC and just ensure enough memory is available so memory leaks during the trading hours would not matter before the application will be restarted.
[–] pjmlp 5 hours ago
Just like plenty of C and C++ deployment scenarios have special purpose memory allocators, or forbid memory allocations other than at startup.

Yet one still needs to account with processes like MISRA to account for safety.

[–] fpoling 6 hours ago
I worked on a project with a network server written in Go with soft realtime requirements. In theory Go should be very good fit for it especially given GC tuning towards low latency, not throughoutput. In practice the latency spikes from GC were bad and there were no good options to resolve those given the deployment constrains and the amount of third-party libraries used.
[–] treyd 10 hours ago
This is a viable approach for many scenarios. Uniffi is a tool/library from Mozilla that makes this a lot easier across platforms.

After a few rounds of this though it might end up seeming like it's not worth the hassle and it's easier to build the whole application in Rust.

[–] vatsachak 10 hours ago
Lifetime and smart pointer hell is real though.
[–] treyd 10 hours ago
Once you internalize it it's really not a problem. That's why I said "after a few rounds of this".
[–] vatsachak 10 hours ago
I've been writing Rust for a year and change professionally, also as a hobby, and even though I love it, it's really annoying to choose the allocation model and lifetime model at every step.

For example,

- A field in a struct cannot borrow another field so now you'd have to create two structs. I guess you could write an impl to borrow that field instead of storing the borrow.

- In simulation software I wrote I found that mimalloc does just as good as bumpalo (within 5%) so carrying a bump everywhere was useless. Not really a rust issue but rather a loss of faith in manual memory management for me.

- Eventually over time you start adding Arc<Fn(Blah)->Foo> everywhere and Box, Arc and friends start coming in. But you can't have cyclical references there so you have to use Weak. And you have to use OnceCell or LazyCell or LazyLock for things that should run at start time.

Rust is really great for the crates, but ...

For applications which are not absolutely performance critical and cannot* be stated pretty easily in linear logic + clone + drop you can get away with Haskell

[–] Mawr 9 hours ago
Switching out the entire ecosystem, libraries, tooling; rewriting the entire codebase; learning the new language and its idioms; and then giving up the unknown benefits of the previous language that the new language lacks (for Go->Rust this could e.g. be compile times)—generally, trading known downsides of a language for unknown downsides of another—is a huge undertaking and therefore very unlikely to ever be worth the hassle.
[–] hoppp 10 hours ago
I agree. If the use-case requires no GC then Rust or Zig or C++ is a better fit.

I don't see much point in choosing a language just to bypass it's features.

[–] cpgxiii 10 hours ago
Coming from an environment in which we extensively use mixed codebases (C++ and Python) to combine performance and ease of prototyping, one of the pain points is that there is almost always some impedance mismatch between the lifetime/ownership models of the two languages. When something goes wrong here, it's usually a real pain to debug and resolve, and often the resolution involves imposing constraints from one language onto the other (e.g. C++ that would idiomatically use unique_ptr instead needs to use shared_ptr because unique_ptr is essentially impossible to completely capture in Python).

Given the issues involved in mixing languages, there can be cases where sticking with one "good enough" GC'd language and having to write a few performance-sensitive parts in very unidiomatic form to minimize/eliminate GC work is preferable.

[–] revengerwizard 10 hours ago
I feel like that may be more of an issue with how Python's C API is designed, leaking basically most of its internals, and then having to remember to manage (increment/decrement) Python objects correctly.
[–] cpgxiii 5 hours ago
I don't think that's the problem, at least not directly for us. The immediate interface between the languages is handled by a binding layer (e.g. pybind11 or nanobind), but that rarely lets you fully express object relationships (something that would be more possible without the binding layer) so it is very easy to either not capture ownership (and thus the C++ object is destroyed out from underneath you) or express a cycle that cpython can't understand (and thus the C++ objects are never destroyed and can leak a significant amount of memory). Explicit manual control would avoid that, but at a level of work that would be prohibitive of having extensive bindings in the first place.
[–] eptcyka 8 hours ago
Go really sucks at calling into C code.