Julia position in the Debian Benchmark Game can be improved, and categorization of some Julia there is unfair

https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/binarytrees-java-7.html

Why is Java here 2.7x faster than Julia? It doesn’t seems cheating, i.e. not using memory pools (is using a thread pool that is ok; Julia also uses threads). All faster programs, i.e. the non-GC languages, use memory pools.

(Lisp and) OCaml aren’t far behind, and it has a comment:

(* Gc.set { (Gc.get()) with Gc.minor_heap_size = 1024 * 1024; max_overhead = -1; }; *)

It’s actually a hint to the GC, and maybe Java is similarly good without needing a hint. Can Julia match this (i.e. without a memory pool)? Feel free to also implement with a pool.

I’m unsure, does Java (and seemingly C#) allow heap compaction (I’m unsure if this is still used in practice, only in old GC implementations?)? Does it make it faster? I can’t actually see how it can be faster, if it moves memory around (that’s an overhead), which is not possible in Julia (since it must be able to call C?), but why was that ever done historically at least? If not for performance reasons?

https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Step 2a: Deletion with Compacting
To further improve performance, in addition to deleting unreferenced objects, you can also compact the remaining referenced objects. By moving referenced object together, this makes new memory allocation much easier and faster.

I’m unclear on how this can work at all without changing all pointers to the still-used regions, and indirection doesn’t seem like would help for performance. Pointers aren’t used much in Julia, but you can get pointers to heap objects, e.g. for calling C, so it rules this out. Is there a way to support it when you know pointers not needed?

All the faster GC-langugages there seem to have or support compacting GC (Java is using its default GC, one of many, haven’t confirmed it’s compacting).

Haskell is even faster, 3.4x Julia’s time, but it opts into some non-GC tracked memory, unsure if it’s compacting, seems more like a memory pool.

https://www.reddit.com/r/haskell/comments/fxr4oj/ghccompact_and_the_new_gc/

We’re 47% slower than even Erlang, and it compacts (unless no longer using such GC).

Go is NOT compacting, and is 2x slower than Julia, so kind of supports my theory.

Go trades the complexity of a compacting GC for forcing you to restart the app regularly if you have a workload with plenty of heap allocation.

Lisp SBCL (2.36x faster) probably compacts, i.e. this is about some alternative, not good enough, because it doesn’t(?):
Parallel garbage collection for SBCL https://applied-langua.ge/~hayley/swcl-gc.pdf

The collector reclaims memory and allows for bump allocation without the collector needing to move objects, using a mark-region heap based on Immix … The parallel garbage collector using one core usually is slower than the copying collector of SBCL, outperforms copying with two cores, and continues to scale with more cores. …
The collector is not ready to be used in production yet, lacking support for the immobile space of SBCL, and lacking any kind of compaction.

Go moving to compacting/copying GC (but not yet?):

Three garbage collectors: Java, Python, and Julia https://indico.cern.ch/event/1329685/contributions/5597296/attachments/2777423/4840807/hsf-accelerator-pivarski-gc.pdf

physicists are more interested in Julia than, say, Rust or Lua

Python has 3 generations (also not compacting) and Julia “1 bit = 2 generations”.

2 Likes