Live data from Hacker News

Reference count, don't garbage collect

kevinlawler.com

361–370 of 415 posts

Re: Reference count, don't garbage collect

#361

Earlier quoted context omitted.

The best real world garbage collectors are like ZGC, Shenandoah or C4 which don't pause your program at all. They are fully concurrent. Even if you go for a GC that is designed to balance throughput and latency, like G1, you can still configure what pause times it should target and those can easily be ~10-20msec if you want, with the vast majority of pauses being far less than that (less than 3 msec). "I was recently…

Serious questions: if these garbage collectors are so good, why aren't they widely used? My guess is that they have downsides such as low throughput, high CPU usage, high memory usage, etc... You can't import a JVM GC into V8, to stay with my example, but you can reimplement the ideas if you have quasi-infinite money like Google.

For ZGC/Shenandoah because they're new, and they're new because they're extremely hard to implement well. For C4 because it is expensive and requires kernel patches. Also there isn't a whole lot of need for them in many use cases. Web servers for example have far bigger latency problems than GC, normally. Pauseless GC was historically driven by the HFT/finance sector for that reason.

Also yes, pauseless GC tends to have higher overheads than GC that pauses for longer. Whether that matters or not depends a lot on the use cases and actual size of the overheads. For example ZGC is pauseless but not yet generational. Generational ZGC when it launches will improve throughput significantly.

Google haven't done pauseless GC for V8. I don't know why not because they have done one for Android. ART uses a fully concurrent collector iirc. At any rate, although you can't import a JVM GC to V8, you can run JavaScript on the JVM using GraalJS and use the GCs that way. Though I don't recall off hand if Graal supports ZGC yet. There's no deep reason why it couldn't.

Re: Reference count, don't garbage collect

#362
post #341
post #272

Earlier quoted context omitted.

https://github.com/ixy-languages/ixy-languages The real reason why a tracing GC was a failure in Objective-C was due to the interoperability with the underlying C semantics, where anything goes. The implementation was never stable enough beyond toy examples. Naturally automating the Cocoa release/retain calls made more sense, given the constraints. In typical Apple fashion they pivoted into it, gave the algorithm a f…

> What Apple has is excellent marketing. Whoa! Marketing? Interop with C is a MASSIVE use-case. And iOS is A LOT faster and more responsive than android. That is, right there, total proof that can't denied. I do both, and the speed of apple way and the simplicity of bridge the C-abi is not a joke.

The android/iOS comparison has many more factors than GC type. I suspect the main difference is processor type - Qualcomm ARM has been very disappointing so far, and GC type doesn't even come into it.

Re: Reference count, don't garbage collect

#363
post #294

Earlier quoted context omitted.

You're assuming RC requires atomics. Just like GCs have been improving so have RCs. There are several designs for modern non-atomic RCs with various solutions for passing data between threads. It generally improves performance significantly better than atomic RCs, for the cache reasons you point out. Though yes reference counting does increase the size of small objects. I find the performance edge depends on the use…

Without atomics, lock free algorithms are required, which without adequate CPU support are very hard to get right.

Lock free algorithms generally require atomics. The non-atomic RCs use other algorithms to eliminate or at least reduce atomics. The main detail is that the bulk of normal incr/decr's are non-atomic.

Re: Reference count, don't garbage collect

#364
Reference counting forces the developer to think about memory management.

Apple has a nice talk on ARC [1] but it got me thinking: if I have to think about reference counting this much I might just as well manage memory all by myself.

The true joy of Garbage Collection is that you can just create objects left and right and let the computer figure out when to clean them up. It's a much more natural way of doing things and lets computers do what they're best at: taking tedious tasks out of the hands of humans.

[1]: https://developer.apple.com/videos/play/wwdc2021/10216/

Re: Reference count, don't garbage collect

#365
post #293

Earlier quoted context omitted.

> to claiming it's even faster than hand optimized C++, which is quite honestly unbelievable - whatever the reference counting algorithm is doing can be emulated by the hand-optimised C++ code so that's just literally impossible. There is nuance here. They claimed that their project is faster than a specific hand optimized project. Not faster than a theoretical peak performance c++ program. I've run into similar situ…

> And %timeit in the ipython shell is way easier than the black magic involved in profiling and benchmarking java Unfair criciticm... first, Java has had a REPL for several years and you can time stuff like in Python as easily... second, profiling tools in Java are some of the best available, and are not blackmagic... quite simple to use, just attach them to the running process and hit "profile". With that said: yes,…

No post body was provided.

Re: Reference count, don't garbage collect

#366

Earlier quoted context omitted.

Not my experience at all. I am maintaining a very high performance JIT compiler for a Haskell like programming language used in production at large enterprises around the world. So I am used to very carefully analyse performance. And reference counting is never the bottleneck. You might be right in theory but not in practice.

Not sure about the characteristics of your workload, but here's a talk where a group wrote device drivers in several high-level languages, and measured their performance: https://media.ccc.de/v/35c3-9670-safe_and_secure_drivers_in_... They found that the Swift version spent 76% of the time doing reference counting, even slower than Go, which spent 0.5% in the garbage collector.

All that tells me is that the Swift implementation is different from the one I implemented.

Re: Reference count, don't garbage collect

#367

Earlier quoted context omitted.

The builder pattern with method chaining is unfortunate and should usually be replaced by named/optional parameters, in any sensible/modern programming language at least. IDEs are an enabler for horriblyLongIdentifierNames because they enter them for you automatically without requiring you to type them on a keyboard.

Can you explain why you feel this way? I personally hate named and optional parameters, as they inevitably seem to drastically inflate the complexity of the function. I would much rather deal with a builder class that encapsulates doing something over calling a method with fifteen parameters, half of which are optional. And god forbid you have optional bool args! If I need to call a monster like that repeatedly, I'm…

One thing I like is that:

    foo(a=1, b=2, c=3)
is shorter (and, I would argue, clearer) than

    foo().a(1).b(2).c(3)
and requires only one method declaration and one method call.

Also for constructors you don't have to worry about partial or out-of-order initialization. Is the above the same as

    foo().c(3).b(2).a(1) ??
What if one call involves opening a file or allocating some resource that is used by another call?

One nice thing that method chaining does give you is being able to differentiate external and internal parameter names. Swift (for example) supports this with argument labels for doing things like

  insert(something, into: list, at: position)
rather than having to use the variable name:

  insert(something, list:list, pos:position)
Of course I wish that Swift supported ObjC/Smalltalk-like syntax so you could just do

   insert a into: list at: position
Note SwiftUI actually uses method chaining for some reason. It's OK but I would have been fine with named parameters.

But I do like Smalltalk's method chaining/cascade syntax:

   robot walkForward; wave; sitDown.

Re: Reference count, don't garbage collect

#368

Earlier quoted context omitted.

Not sure about the characteristics of your workload, but here's a talk where a group wrote device drivers in several high-level languages, and measured their performance: https://media.ccc.de/v/35c3-9670-safe_and_secure_drivers_in_... They found that the Swift version spent 76% of the time doing reference counting, even slower than Go, which spent 0.5% in the garbage collector.

Yeah, GP has no idea what they are talking about. They replied something similar on another thread without ever providing evidence for their claims. They even claimed their RC implementation in Haskell is faster than hand-crafted C++. Gave me a chuckle.

And your reply game me a chuckle :) The code is unfortunately not open source so I can’t provide the evidence. You believe what you want to believe of course. However I am happy to answer any questions on how it is implemented down to the lowest-level nitty gritty details.

Re: Reference count, don't garbage collect

#369
post #216

Earlier quoted context omitted.

Not my experience at all. I am maintaining a very high performance JIT compiler for a Haskell like programming language used in production at large enterprises around the world. So I am used to very carefully analyse performance. And reference counting is never the bottleneck. You might be right in theory but not in practice.

Well, it won’t be the bottleneck itself, but it has an overhead on basically every operation, which likely won’t show up during profiling. Also, I fail to see the advantage of RC in case of a presumably mostly immutable language - a tracing GC is even faster there due to no changes to the object graph after allocation, making a generational approach scale very well and be almost completely done in parallel.

Nope. The compiler does a full program optimisation, reducing the reference counting to an absolute minimum. There is close to zero overhead passing data around. It does not work like C++ shared_pre. shared_ptr is slow.

Re: Reference count, don't garbage collect

#370
post #189

Earlier quoted context omitted.

I wonder how Haskell's purity influences RC usage patterns. Are there tricks which aren't possible in an imperative language?

Haskell specifically is a poor choice of language here, because it creates cycles like the pest. (This is because it uses lazy evaluation, and programming patterns (design patterns?) using lazy evaluation tend to use cyclical references. Strict FP languages might support your point better, but then Ocaml again doesn't work because it mutates like the pest.) Furthermore it also allocates like the pest: busy Haskell pr…

It is a Haskell inspired language but not Haskell. The syntax is similar but it is eagerly evaluated and has no IO and no data cycles. It is used 100% for evaluating complex optimisation and business rules within a client application. The language was carefully crafted to maximise rules writer productivity and execution performance.
Post reply on HN