3 ms·
JIT compilers, games, database server. Anything where you need high performance and do a lot of allocations.
by snek_case 4y ago
JIT compilers, games, database server. Anything where you need high performance and do a lot of allocations.
- kaba0 4y agoJIT compilers don’t actually need that low-level programming, and compilers in general use memory in a very haphazard way so they are likely better off with a GC. In fact, you probably loose way more by not being able to write as many/great optimizations in a low-level language than what you lose on a slight overhead — e.g. Java’s Graal JIT compiler is nowadays performing better (written in Java itself) than the “original” C2 compiler which is written in C++. But this is mostly a maintainability question.
- titzer 4y agoI second that; there is nothing inherent about a JIT that requires low-level memory tricks, except that last step of making the machine code executable and callable. I'm not sure that Rust is a good fit for optimizing compilers, either. E.g. most compiler IRs are fundamentally graph-based and use unrestricted cycles. TurboFan in V8 uses arena-style allocation, as do most of the JITs in other JSVMs, mostly because managing every single node is overkill. A GC with a big enough young gen will do well for the kinds of allocation patterns of a JIT.
- snek_case 4y agoFirstly, an arena-based allocator is a custom allocator, which is something most programmers never need to touch and probably don't know even know about. It is a "low-level memory trick". Secondly, we were talking about how Zig makes allocation first-class. This is a prime use case: specifying your own custom arena-based allocator.
- cmrdporcupine 4y agoIndeed, having played with doing compiler / parser / transformation type work (for relational query transformation, etc) in Rust, and got stuck in a maze of borrow-checker disasters around the tree of references... what I'd say is: this kind of thing is actually better done in a higher level statically typed garbage collected language. For myself, I'd use a mature functional something like OCaml/StandardML or a Lisp or similar. It's just easier to not have to worry about borrow checking references and allocation issues when writing stuff like that. The case against garbage collection is where latency is key. P95, P99 latency always suffers under any kind of garbage collector, no matter how advanced. You can minimize pauses, you can move them around, you can play with different collector aspects, but in the end... compare to explicit allocation/destruction/lifetime mgmt, it's going to suffer. I don't think compilers generally have these latency concerns. Throughput matters, but not the odd unpredictable pause. There's only so many application domains where that is super important: Certain kinds of high traffic servers, database engines [not so much query parsing & planning, but execution, data structures, buffer mgmt, networking], operating systems, and games. Also embedded systems where a tight memory profile is important. I like Rust (and Zig) but sometimes when people have a good hammer, they go looking for nails where there aren't any... (All that said, I feel like some tree/DAG-heavy problems in garbage collected languages could benefit from static (and runtime) reference analysis tools that look a lot like Rust's borrow checker, purely for code sanitation/tracing. Also, GC tracing and some of the programming patterns GC encourages can cause havoc on L1 caches reducing throughput as well as a side-effect, so there's that)
- gpderetta 4y agoStill major compilers and optimizers are written in C and now C++. GCC was written in C with a custom GC. They have moved to C++ and, as as far as I understand, doing more and more with RAII instead of GC (turns out that peak memory usage is a major factor in compiler performance)
- cmrdporcupine 4y agoThat's fair, and I'm not a compiler engineer so I'll avoid making authoritative claims :-). But a C/C++ compiler is a whole thing, with some pretty intense performance requirements, wouldn't you say? Mainly I was speaking from the experience of trying to write more complicated parser & tree transformation pieces in Rust and finding the ownership stuff a hassle.