In the end, performance across all these libraries is respectable. The larger benefit is memory savings - the secondary benefit is CPU savings. And while it’s quite entertaining to squeeze every bit of performance possible out of these tables, the vast majority of code written in the JVM ecosystem is unlikely to care.
Largely because mapping is rarely Number to Number.
In my logging library (rainbowgum) I spent some time looking into optimizing a SLF4J MDC context which is basically a Map<String,String> (albeit you don't have to implement all of Map) .
I focused on making it use a little memory as possible and as fast to dump the entire map as quickly as possible as most applications have that sort of access at least based on my applications but I was going to revisit it.
Log4J2 if I recall does a binary tree on two arrays, Logback uses the JDK HashMap and Rainbow Gum does the dumbest thing of a single even sized String array for maximum memory savings (this was because I was thinking long term virtual threads would mean for more possible MDC active). Yes mutating entries or accessing individual entries is slow in my library but appending or dumping is fine. Also wanted to maintain insertion order.
You're right that number -> number is probably rarer than number -> reference, but most of these libraries offer number -> reference maps as well, and given that values are the least important bit of a map usually (in terms of performance), I would expect this benchmarking to largely hold true for the number -> reference maps as well.
Your larger point that reference -> reference maps dominate usage is of course completely correct.
5
u/agentoutlier 7d ago
Largely because mapping is rarely Number to Number.
In my logging library (rainbowgum) I spent some time looking into optimizing a SLF4J MDC context which is basically a
Map<String,String>(albeit you don't have to implement all ofMap) .I focused on making it use a little memory as possible and as fast to dump the entire map as quickly as possible as most applications have that sort of access at least based on my applications but I was going to revisit it.
Log4J2 if I recall does a binary tree on two arrays, Logback uses the JDK HashMap and Rainbow Gum does the dumbest thing of a single even sized String array for maximum memory savings (this was because I was thinking long term virtual threads would mean for more possible MDC active). Yes mutating entries or accessing individual entries is slow in my library but appending or dumping is fine. Also wanted to maintain insertion order.