Skip to main content

Command Palette

Search for a command to run...

Array vs Linked List: Memory, Cache, and Performance

Updated
6 min readView as Markdown
Array vs Linked List: Memory, Cache, and Performance

An array is like a bookshelf where you can grab any book instantly by its index. A linked list is a treasure hunt where every node only knows where the next one is. This makes searching a linked list slow—requiring you to hop through every single node—while arrays offer instant, direct access.

I like to think of searching for data in a linked list like walking into my kitchen for a pint of milk, opening the fridge, and finding a post-it note that says: "Check the microwave." I walk over, open the microwave, and find another note: "Look under the couch."

To me, this chaotic, step-by-step scavenger hunt is the perfect mental model for a linked list. Every node has a strange kind of amnesia; it knows its own value, but it has no idea where the rest of the list is—it only knows how to find the very next item. While I appreciate the high drama of this design, it is a terrible way to build predictable, high-performance software. Let's look at why I prefer the boring predictability of arrays.

Why is searching a linked list slower than an array?

I always point out that searching a linked list is slower because it lacks random access; you must hop through the list sequentially from the head node. In contrast, I prefer arrays because they store elements contiguously in memory, allowing the CPU to calculate the exact address of any element instantly using its index.

If I need the 500th item in a linked list, I have to find node 1, read its pointer to find node 2, and repeat this process 499 times. That is O(N) lookup time, and frankly, it's highly inefficient.

With an array, I think of it like a beautifully organized bookshelf. Every slot is numbered sequentially. If I need the 500th book, I don't need to read the first 499 covers; I can reach directly to slot 500. Mathematically, the CPU just calculates base_address + (500 * element_size) and jumps there instantly in O(1) time.

How do arrays and linked lists handle memory allocation?

When I look at memory allocation, arrays claim a single, continuous block of memory up front, which keeps elements tightly packed. I find that linked lists do the exact opposite, dynamically allocating memory for each individual node and scattering them across random addresses in heap memory.

I think this physical layout difference is where the real performance battle is won or lost, thanks to how modern CPU caches work. When a CPU reads a value from memory, it doesn't just grab a single byte. It fetches an entire chunk of neighboring memory—a cache line—into its ultra-fast L1/L2 cache.

  • Arrays take advantage of this: Since array elements sit side-by-side, loading the first element means the next several are likely already sitting in the cache.
  • Linked lists waste this: Because those "post-it notes" are scattered all over the place, I find that every pointer hop forces the CPU to suffer a "cache miss" and fetch data from the much slower main RAM.

When should you actually use a linked list instead of an array?

I recommend using a linked list when your application requires frequent, O(1) insertions or deletions at the beginning of a list without shifting elements. I also find them useful when you cannot predict the final size of your data structure and want to avoid the cost of resizing arrays.

If we look at how these structures handle modifications, arrays can be painful. To insert an item into the middle of an array, I have to shift every subsequent element over by one slot in memory. A linked list avoids this because I only need to change the pointers of the neighboring nodes.

Here is how I visualize these trade-offs across common operations:

Operation / Metric Array (or Array List) Linked List
Lookup by Index O(1) (Instant) O(N) (Must traverse)
Insert/Delete (Start) O(N) (Must shift all elements) O(1) (Just change pointers)
Insert/Delete (End) O(1) amortized O(1) (With a tail pointer)
Memory Overhead Low (Only data elements) High (Data + pointer per node)
Cache Friendliness High (Sequential memory) Low (Fragmented heap memory)

How does this affect real-world application performance?

In my view, the theoretical insertion benefits of linked lists are often a trap because finding the insertion point itself requires an O(N) sequential search. Consequently, I almost always default to standard dynamic arrays (like Python's lists or Java's ArrayList) unless I am building specific low-level structures like queues.

I often see developers get excited about "constant time insertion" without realizing they still have to traverse the list to find where to insert the item. That search operation wipes out any performance gains. For almost all daily engineering tasks, I find that the hardware-level cache friendliness of arrays beats the theoretical flexibility of linked lists.

FAQ

Why does a linked list have higher memory overhead?

To me, the biggest hidden cost is the pointer overhead. Every node in a linked list must store not just the actual data payload, but also the memory address (pointer) of the next node. On a 64-bit system, each pointer consumes 8 bytes of memory, which can easily exceed the size of the actual data you are storing.

What is the difference between a singly linked list and a doubly linked list?

I distinguish them by their directional capabilities. A singly linked list only contains a pointer to the next node, allowing traversal in one direction. A doubly linked list contains pointers to both the next and the previous nodes, which lets you traverse backward at the cost of doubling the pointer memory overhead.

Is ArrayList a linked list?

I get asked this a lot, and the answer is a hard no. Despite having "List" in the name, an ArrayList is backed by a standard array. It manages resizing automatically behind the scenes by allocating a new, larger array when it runs out of space, meaning you still get the fast O(1) random access of an array.