220hertz 54 minutes ago

I used to write a lot of Javascript-like Extendscript scripts back when I was using InDesign a lot. The DOM's global object $ had a method to directly invoke the garbage collector. It made a difference certainly, but it was difficult to tell to what extent because InDesign itself gradually leaks memory and becomes more bloated the longer you use it in a single session.

bjourne 6 minutes ago

Props for using a correct nomenclature. Reference counting is a "kind of automatic garbage collection. Tracing garbage collection is also a kind of automatic garbage collection.

shivanshuag 3 days ago

Agreed, for most real world softwares, the cost of GC is irrelevant. But there are still some programs like databases or game engines where the cost can start adding up. That's when you measure and optimize.

  • pjmlp 1 hour ago

    Yet the three major game engines Unreal, Unity and Godot all have a GC on their infrastructure, and Capcom is quite happy with their .NET fork on RE Engine.

    Also every single graphics application that uses Metal or DirectX, relies on reference counting as GC algorithm.

    • slopinthebag 40 minutes ago

      I’m sure those three engines have had no issues with performance whatsoever right?

      Oh shit…

      • izacus 34 minutes ago

        Do you have any source taking about GC caused performance issues in those engines?

      • pjmlp 31 minutes ago

        I am sure that many of the issues were a skills issue as well.

      • jmull 24 minutes ago

        Game developers are always trying to push the boundaries. The only game engines without performance issues are ones hardly being used.

  • marcosdumay 58 minutes ago

    > That's when you measure and optimize.

    How do you "optimize" the GC away after you wrote your entire database server in a language that uses it?

    • ApolloFortyNine 43 minutes ago

      It's incredibly in common in game development, C# has a lot of features you can take advantage for this.

      But the most naive example any language supports is simple object pooling.

      Then more fancy, zero allocations tasks in C# https://github.com/cysharp/unitask

    • jmull 31 minutes ago

      GC languages typically have features of the language and/or standard library that make GC the default, not the only option.

miladyincontrol 3 days ago

What does GC cost? For Caddy with an incredibly synthetic http only benchmark it costs about 2ms of latency and somewhat less throughput. Worth it in an incredibly artificial benchmark? Perhaps. However when it comes to real world usage the cost is a significantly smaller piece of the pie.

thomashabets2 48 minutes ago

> In Rust you pay for it by arranging your program in a way the compiler can verify.

I disagree with this. The sentence implies that this work is done in order to make the compiler happy, where my experience is that it forces the programmer to actually get it right.

I had an "aha moment" when I was frustrated at failing to express my intent to the compiler, and suddenly realised that the reason I couldn't "just say the magic words" was that my object ownership design was inherently flawed. I had to make large changes not to make the compiler happy, but to actually have a coherent design.

So no, it's not about what "the compiler can verify". That's like saying "my lawyer won't let me do this". No, your lawyer is your employee, not your boss. They're just saying that if you do this, then you may go to prison. It's not the same thing.

("unsafe" is the Rust way to go "thank you, legal department, but I'm making a business decision to take this risk. Your concern has been noted")

  • ron_k 25 minutes ago

    I understand what you’re saying, but I read that phrase in a different way.

    Let’s say you have two ways of doing the same thing: both work, both are legit and neither introduce GC bugs. The only difference between the two is that one can be verified by the compiler while the other can’t, so you are stuck with solution no. 1 although both would work.

    To phrase it differently: the code that gets verified by the compiler is safe, but is all safe code verifiable by the compiler?

    I’m not implying that’s the case, but that’s what I feel the author is saying.

    • thomashabets2 6 minutes ago

      > To phrase it differently: the code that gets verified by the compiler is safe, but is all safe code verifiable by the compiler?

      Right. And this reduces to the halting problem, so in theory the compiler cannot know that all safe code is safe.

      In practice, I'm saying that not just syntactically, but in your code's design, the compiler is more likely to be right. It's a bit like Chesterton's fence. You can bypass the lifetime checks if you just have the confidence to say "yes, I'll use `unsafe` here and it's fine because these reasons". As you're writing your "SAFETY" comment, you may very well find yourself not so confident anymore. And indeed, often this compiler-induced "stop and think" prevented you steaming ahead with a bug.

      Now, the borrow checker is not perfect. I don't know how far away from "all but NP-complete cases" it is. My experience is that it's almost always right, and I've only had to put a seemingly needless "drop" statement to placate it. But they're working on it. A new one is coming: https://daily.dev/posts/rust-s-new-borrow-checker-is-coming-...

      And once again this old blog post of mine comes to mind: https://blog.habets.se/2020/12/Bypassing-safety-check-for-ob...

      In any case "by arranging your program in a way the compiler can verify" I think is not accurate, because the overlap between "correct" and "compiler can verify" is nearly complete, though yes the latter is a strict subset of the former. In other words I don't write Rust to make the compiler be able to verify it, but to make it correct. And nearly always that means the compiler can verify it too.

  • convolvatron 5 minutes ago

    I've had that moment in Rust too, where there was no composition that affected what I wanted, because supporting that model would have meant a very different backing data structure. However in that case I actually didn't care about the kind of correctness problem it was saving me from.

    I've also had the converse experience, where I know full well that the structure I'm trying to impose is correct and quite efficient, but its part of the space that rust doesn't cover.

    Rust is great. It's a noble attempt to bring a degree of correctness to a problem space that suffers from a great deal of slop. But to pretend that the model is complete, or that the design decisions that were made are perfect in every way, is just wrong. That the rust compiler and runtime can't support my construct isn't really an absolute value judgement on that idea in the first place. The rust compiler isn't really an oracle that tells you whether something is right or not in an arbitrary value system.

pclowes 1 hour ago

This is one of the best high-level survey explanations of GC I have seen, nice work.

amazingamazing 37 minutes ago

I rarely see a real use case bottle necked on garbage collection.

EGreg 45 minutes ago

There is no need for garbage collection if you don’t form circular references. Just have a canonical direction and always keep weak references the other way.

  • thomashabets2 34 minutes ago

    Reference counting is a different model. Many papers have explored the differences and similarities, and your comment leaves so much out that it cannot even be said to be true or false.

    I'd say GC is always the fastest to free objects within the main code path. Literally zero instructions.