Hacker News new | ask | show | jobs
by pjmlp 2008 days ago
Usually it boils down to cargo cult against GC based languages instead of learning how to use all their features, including those for C++ like resource management.

https://devblogs.microsoft.com/aspnet/grpc-performance-impro...

1 comments

While I can't speak for any experimental new garbage collectors, I did analyze the SBCL generational GC's implementation. I encourage anyone interested in performance to look over GC code and realize how much work they are doing.

That GC in particular has to stop the world, traverse the entire fresh heap, guesses whether something is even a pointer (and can guess wrong, causing a memory leak!), and does all this at arbitrary times, unless you do non-idiomatic things like manage your own memory in preallocated arrays, or use C/asm-powered memory mapped buffers [0].

Nothing comes for free, and some domains can't pay the price for GC (and choose to spend those resources elsewhere). Games, in my opinion, are largely still in that category.

[0] https://m.youtube.com/watch?v=S7nEZ3TuFpA

> unless you do non-idiomatic things

I wonder what exactly makes code "idiomatic" in a GC language. It is one of the greatest misconceptions about GC languages that you shouldn't worry about allocations at all. For me, GC mostly means the correctness guarantees which come with it and the convenience, that I don't have to track every single allocation and mange it manually. However, it still means that I should be aware of all the larger allocations and avoid them as in any other language, if I am looking for performance. Not reusing allocated memory where reasonable is detrimental to the performance in any language. And of course, the choice of the right GC approach can also help with applications like games. Lispworks even provided a Lisp environment for a Nasa probe, the GC had real-time capabilities.

Like the ones written in Unreal?

https://docs.unrealengine.com/en-US/ProgrammingAndScripting/...

Just because a language has a GC doesn't mean one needs to use it 100% of the time, which is exactly what is behind the .NET 5 performance improvements that top C++.

By making use of stack allocations, value types, memory slices, native heap allocations.

Features that Common Lisp also supports, and I bet Allegro and LispWorks are better than SBCL in the performance chapter.

It depends on what you talk about with "performance". Some years ago, Allegro had the faster GC than SBCL, but SBCL certainly had the best code generator of the three Lisps. So unless your runtime is constrained by the GC, SBCL really shines for performance. And it gives you a lot of knobs to optimize the memory usage.
SBCL generates the best code for toy benchmarks and number crunching applications. Throw it against a CLOS heavy codebase and you'll be surprised at how it runs VS Clozure CL and the aforementioned implementations.

ACL's GC is still the best hands down (and of course ABCL by virtue of the JVM). I think SBCL is still sporting a conservative GC on x86.

Not sure what you meant by "toy benchmarks", but to me this has a very negative connotation. The SBCL compiler excells at complex code and regularly produces much better output than most Lisp compilers. CLOS is a very bad example for judging the compiler quality, because its performance heavily depends on the implementation. To compare compilers, you would have to use the identical underlying CLOS implementation. A bad one can ruin your performance independantly of the compiler used. To make comparisons, one needs benchmarks where the whole code in question is compiled by the different compilers.

To my knowledge, SBCL switched to a precise GC some time ago. But I still would expect ACL's GC to outperform the SBCL one.