ExerciseWarm-up
Warm-up
Time the two lists yourself
5 minfresher0–4 yrs
One concept, guided. Near-impossible to fail.
What this teaches
- Random access on a LinkedList walks the chain, so it is orders slower
- Iteration with for-each is a draw; index loops over LinkedList are O(n^2)
- Mid-list insertion goes to ArrayList, against the folklore
- LinkedList wins only at the head
Starter
Starter.java
import java.util.*;
/**
* Warm-up: measure, don't recite.
*
* Before you run this, write down which list you expect to win each of the four
* operations. The exercise is worthless if you skip that step — the point is to
* be wrong on paper, once, so you remember it.
*/
public class Starter {
static final int N = 50_000;
static final int INSERTS = 10_000;
static long ms(Runnable r) {
long start = System.nanoTime();
r.run();
return (System.nanoTime() - start) / 1_000_000;
}
static void sink(long v) {
if (v == Long.MIN_VALUE) System.out.print("");
}
static void bench(String label, List<Integer> list) {
for (int i = 0; i < N; i++) list.add(i);
Random rnd = new Random(42);
int[] idx = new int[5_000];
for (int i = 0; i < idx.length; i++) idx[i] = rnd.nextInt(N);
long get = ms(() -> { long s = 0; for (int i : idx) s += list.get(i); sink(s); });
long iterate = ms(() -> { long s = 0; for (int v : list) s += v; sink(s); });
long middle = ms(() -> { for (int i = 0; i < INSERTS; i++) list.add(list.size() / 2, i); });
long head = ms(() -> { for (int i = 0; i < INSERTS; i++) list.add(0, i); });
System.out.printf("%-11s get=%dms iterate=%dms insert-mid=%dms insert-head=%dms%n",
label, get, iterate, middle, head);
}
public static void main(String[] args) {
// Untimed pass so the JIT has compiled the loops before we measure.
bench("(warmup)", new ArrayList<>());
bench("(warmup)", new LinkedList<>());
System.out.println("--- measured ---");
bench("ArrayList", new ArrayList<>());
bench("LinkedList", new LinkedList<>());
// TODO 1: which result differs most from what you predicted?
// TODO 2: add a fifth measurement — an INDEX loop:
// for (int i = 0; i < list.size(); i++) sum += list.get(i);
// Run it on both. Start with N = 50_000 and be ready to wait.
// Then explain why it is not the same as the for-each iterate result.
// TODO 3: add ArrayDeque to the head-insertion comparison. It is not a
// List, so you will need a Deque variable. Does it beat LinkedList?
}
}Run it locally:
cd exercises/java/collections/arraylist-vs-linkedlist/01-warmup
javac Starter.java -d /tmp/out && java -cp /tmp/out StarterDone when
- You wrote your prediction down before running it
- You can say which of the four results surprised you and why
- You changed the index loop to for-each and saw the difference
← Back to When would you use LinkedList instead of ArrayList?