Quantcast
Viewing latest article 5
Browse Latest Browse All 36

Answer by Lior Bar-On for When to use LinkedList over ArrayList in Java?

TL;DR due to modern computer architecture, ArrayList will be significantly more efficient for nearly any possible use-case - and therefore LinkedList should be avoided except some very unique and extreme cases.


In theory, LinkedList has an O(1) for the add(E element)

Also adding an element in the mid of a list should be very efficient.

Practice is very different, as LinkedList is a Cache Hostile Data structure. From performance POV - there are very little cases where LinkedList could be better performing than the Cache-friendlyArrayList.

Here are results of a benchmark testing inserting elements in random locations. As you can see - the array list if much more efficient, although in theory each insert in the middle of the list will require "move" the n later elements of the array (lower values are better):

Image may be NSFW.
Clik here to view.
enter image description here

Working on a later generation hardware (bigger, more efficient caches) - the results are even more conclusive:

Image may be NSFW.
Clik here to view.
enter image description here

LinkedList takes much more time to accomplish the same job. sourceSource Code

There are two main reasons for this:

  1. Mainly - that the nodes of the LinkedList are scattered randomly across the memory. RAM ("Random Access Memory") isn't really random and blocks of memory need to be fetched to cache. This operation takes time, and when such fetches happen frequently - the memory pages in the cache need to be replaced all the time -> Cache misses -> Cache is not efficient.ArrayList elements are stored on continuous memory - which is exactly what the modern CPU architecture is optimizing for.

  2. SecondaryLinkedList required to hold back/forward pointers, which means 3 times the memory consumption per value stored compared to ArrayList.

DynamicIntArray, btw, is a custom ArrayList implementation holding Int (primitive type) and not Objects - hence all data is really stored adjacently - hence even more efficient.

A key elements to remember is that the cost of fetching memory block, is more significant than the cost accessing a single memory cell. That's why reader 1MB of sequential memory is up to x400 times faster than reading this amount of data from different blocks of memory:

Latency Comparison Numbers (~2012)----------------------------------L1 cache reference                           0.5 nsBranch mispredict                            5   nsL2 cache reference                           7   ns                      14x L1 cacheMutex lock/unlock                           25   nsMain memory reference                      100   ns                      20x L2 cache, 200x L1 cacheCompress 1K bytes with Zippy             3,000   ns        3 usSend 1K bytes over 1 Gbps network       10,000   ns       10 usRead 4K randomly from SSD*             150,000   ns      150 us          ~1GB/sec SSDRead 1 MB sequentially from memory     250,000   ns      250 usRound trip within same datacenter      500,000   ns      500 usRead 1 MB sequentially from SSD*     1,000,000   ns    1,000 us    1 ms  ~1GB/sec SSD, 4X memoryDisk seek                           10,000,000   ns   10,000 us   10 ms  20x datacenter roundtripRead 1 MB sequentially from disk    20,000,000   ns   20,000 us   20 ms  80x memory, 20X SSDSend packet CA->Netherlands->CA    150,000,000   ns  150,000 us  150 ms

Source: Latency Numbers Every Programmer Should Know

Just to make the point even clearer, please check the benchmark of adding elements to the beginning of the list. This is a use-case where, in-theory, the LinkedList should really shine, and ArrayList should present poor or even worse-case results:

Image may be NSFW.
Clik here to view.
enter image description here

Note: this is a benchmark of the C++ Std lib, but my previous experience shown the C++ and Java results are very similar. Source Code

Copying a sequential bulk of memory is an operation optimized by the modern CPUs - changing theory and actually making, again, ArrayList/Vector much more efficient


Credits: All benchmarks posted here are created by Kjell Hedström. Even more data can be found on his blog


Viewing latest article 5
Browse Latest Browse All 36

Trending Articles