Abstract: Every schoolboy knows that arrays are faster than linked structures, no matter the language. In this newsletter we present a puzzle where we find LinkedList outperforming ArrayList for ZGC. Let's see who comes up with the most thorough explanation why.
Welcome to the 334th edition of The Java(tm) Specialists' Newsletter. In May 2026 I am speaking at the JNation Conference in Coimbra, Portugal. It is my first visit to Portugal, and I'm very excited. I was supposed to go last year, but had to cancel last minute. JNation is sold out for 2026, so be sure to grab a seat for 2027 as soon as it opens up. The speaker lineup looks amazing, with 1/4 Java Champions! I will also be speaking at the Lisbon JUG.
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
By now, I hope that you have learned to never use LinkedList. Even the
author of the class famously tweeted
that he never uses it. Since Q3 last year, requests for the Java 25
version of my "Extreme Java - Concurrency Performance
Courses" have steadily increased. We had an amazing in-house
class last week, with excellent engineers and insightful questions. Towards
the end of the course, when we were looking at performance, someone asked
about LinkedList. I wrote a quick demo that showed how long it would take
to insert 100m elements into ArrayList vs LinkedList. It was not meant to be
a thorough benchmark, just something hacked together on the fly to quickly
answer a question. It looked somewhat like this:
import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.function.*;
public abstract class ListPuzzle {
void run(Supplier<? extends List<Integer>> supplier) {
var tmb = ManagementFactory.getThreadMXBean();
var tim = System.nanoTime();
var cpu = tmb.getCurrentThreadCpuTime();
var usr = tmb.getCurrentThreadUserTime();
try {
var list = supplier.get();
System.out.println(list.getClass() + ":");
for (var i = 0; i < 100_000_000; i++) {
list.add(42);
}
} finally {
tim = System.nanoTime() - tim;
usr = tmb.getCurrentThreadUserTime() - usr;
cpu = tmb.getCurrentThreadCpuTime() - cpu;
System.out.printf("tim=%d,", (tim / 1000000));
System.out.printf("cpu=%d,", (cpu / 1000000));
System.out.printf("usr=%d%n", (usr / 1000000));
}
}
}
For ArrayList, we have a simple subclass:
public class ArrayListPuzzle extends ListPuzzle {
void main() {
run(java.util.ArrayList::new);
}
}
Similarly, for LinkedList:
public class LinkedListPuzzle extends ListPuzzle {
void main() {
run(java.util.LinkedList::new);
}
}
I asked Claude Opus 4.7 which would be faster, and it said "ArrayList - by a wide margin." And this is also what we expected to see. Running Java 25.0.2+10 Amazon Corretto on my MacBookPro M2 Max, with 12 cores (8 performance and 4 efficiency cores) and 96 GB of memory, I see the following results:
class java.util.LinkedList: tim=3205,cpu=382,usr=348
class java.util.ArrayList: tim=439,cpu=363,usr=312
Note that tim is the elapsed time, which we also
call "wall clock time". That is the time that we would see
on our stopwatch if we measured how long it takes to run the
code. Then cpu is how much CPU time is burned.
For a CPU intensive task, we would expect this to be similar
to the elapsed time. Lastely we see the usr
representing user time, of actual work done, as opposed to
waiting for system time wasted on voluntary context switches
and the like. We see clearly that ArrayList
is 7.3x "faster" than LinkedList in terms of
elapsed time. However, when we look at the user time,
ArrayList is only 1.12x "faster".
There are good reasons for the differences, and also why this is a flawed demo.
We can also see how this runs with ZGC:
class java.util.LinkedList: tim=548,cpu=547,usr=374
class java.util.ArrayList: tim=686,cpu=686,usr=582
Hmmm, that's interesting. We now see that the LinkedList is
now 1.25x faster with elapsed time and 1.56x faster with user
time! What gives?
Let's have some fun. There are quite a few different things going on here. Whoever sends me the most thorough explanation gets their name forever immortalized in the next edition of The Java(tm) Specialists' Newsletter. You may gladly use whatever AI tool you like, but please let us know which one(s) you used. Hint: There are quite a few factors in play.
Kind regards
Heinz
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.