11

i thought linkedlists were supposed to be faster than an arraylist when adding elements? i just did a test of how long it takes to add, sort, and search for elements (arraylist vs linkedlist vs hashset). i was just using the java.util classes for arraylist and linkedlist...using both of the add(object) methods available to each class.

arraylist out performed linkedlist in filling the list...and in a linear search of the list.

is this right? did i do something wrong in the implementation maybe?

***************EDIT*****************

i just want to make sure i'm using these things right. here's what i'm doing:

public class LinkedListTest {

    private List<String> Names;

    public LinkedListTest(){
            Names = new LinkedList<String>();
    }

Then I just using linkedlist methods ie "Names.add(strings)". And when I tested arraylists, it's nearly identical:

public class ArrayListTest {

    private List<String> Names;

    public ArrayListTest(){
            Names = new ArrayList<String>();
    }

Am I doing it right?

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
user618712
  • 1,463
  • 7
  • 17
  • 19
  • It depends... What does your test code look like? If you are initializing the ArrayList to a known size, then ArrayList would likely be faster. LinkedList comes with some extra overhead in that each element must be wrapped in a node so it can contain references to prev and next. ArrayList performance issues come from having initialize a completely new backing array when the existing capacity has been reached and copy all elements to the new array. – Mark S Mar 17 '11 at 22:38
  • @Mark - nope, not initializing arraylist to a known size. – user618712 Mar 17 '11 at 22:59

6 Answers6

14

Yes, that's right. LinkedList will have to do a memory allocation on each insertion, while ArrayList is permitted to do fewer of them, giving it amortized O(1) insertion. Memory allocation looks cheap, but may be actually be very expensive.

The linear search time is likely slower in LinkedList due to locality of reference: the ArrayList elements are closer together, so there are fewer cache misses.

When you plan to insert only at the end of a List, ArrayList is the implementation of choice.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • ok, i guess that makes sense. i did some googling...some sites have said that adding to the end or beginning of a linkedlist should be faster than doing the same with an arraylist. why? i also read a site that said the time complexity of the add() method of both linkedlist and arraylist is O(1). what? really?!?! – user618712 Mar 17 '11 at 22:39
  • @user: the append (insert at end) time for `ArrayList` is *amortized* O(1), meaning that it's O(1) on average when doing a long series of appends. Any one of them may be O(n), but that one doubles the capacity so the next *n* of them can use pre-allocated space. – Fred Foo Mar 17 '11 at 22:42
  • @larsmans, cache-misses are major selling point of the array backed up structures. Linked structures are potentially a cache miss on each node making the O(n) iteration actually significantly slower. – bestsss Mar 17 '11 at 23:04
  • @bestsss: I meant that `LinkedList` incurs many cache misses. Edited my anwer for clarity. – Fred Foo Mar 18 '11 at 00:13
  • 1
    Even when the linked list does not include any cache misses at all, the traversal will be slower. This is because visiting each item incurs the cost of two dereference operations instead of the single one that the array list needs. – Zoe Mar 18 '11 at 03:08
  • 1
    Hmmmm, as it turns out, arrays are created with a series of object references, and the objects themselves reside in unrelated parts of memory. If you have an array of objects rather than primitives, it is just as vulnerable to cache miss as the linked list. – Zoe Mar 18 '11 at 03:21
  • @larsmans, my comment was not critic at any rate, I was pleasantly surprised someone (besides me) to mention the cache misses when working w/ a java structure. it was mostly praise. – bestsss Mar 18 '11 at 08:00
  • @Zoe, the cache lines are relatively short - 64 bytes on x86. So w/ 8 bytes reference size, it's 7 cache hits after a cache miss for ArrayList. W/ LinkedList you can assume cache miss on each element (not necessary of course but it's a guess). Cache misses are just too slow compared to any other operation (could be like 100times slower). – bestsss Mar 18 '11 at 08:18
4

Remember that:

  • there's a difference in "raw" performance for a given number of elements, and in how different structures scale;
  • different structures perform differently at different operations, and that's essentially part of what you need to take into account in choosing which structure to use.

So, for example, a linked list has more to do in adding to the end, because it has an additional object to allocate and initialise per item added, but whatever that "intrinsic" cost per item, both structures will have O(1) performance for adding to the end of the list, i.e. have an effectively "constant" time per addition whatever the size of the list, but that constant will be different between ArrayList vs LinkedList and likely to be greater for the latter.

On the other hand, a linked list has constant time for adding to the beginning of the list, whereas in the case of an ArrayList, the elements must be "shuftied" along, an operation that takes some time proportional to the number of elements. But, for a given list size, say, 100 elements, it may still be quicker to "shufty" 100 elements than it is to allocate and initialise a single placeholder object of the linked list (but by the time you get to, say, a thousand or a million objects or whatever the threshold is, it won't be).

So in your testing, you probably want to consider both the "raw" time of the operations at a given size and how these operations scale as the list size grows.

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
1

When adding an element to the back of a LinkedList (in Java LinkedList is actually a doubly linked list) it is an O(1) operation as is adding an element to the front of it. Adding an element on the ith position is roughly an O(i) operation.

So, if you were adding to the front of the list, a LinkedList would be significantly faster.

Argote
  • 2,155
  • 1
  • 15
  • 20
  • 1
    Aren´t Java LinkedLists doubly-linked in reality -- I don't think it should matter which end you add to. – Neil Coffey Mar 17 '11 at 22:39
  • Ah, I don't know the implementation details but that could be true. I'll look into it and delete my answer if necessary. – Argote Mar 17 '11 at 22:41
  • It seems that LinkedList is indeed a doubly linked list, interesting. – Argote Mar 17 '11 at 22:44
  • @Argote - so does that make adding to either end of a linked list slower or faster than adding to an arraylist? – user618712 Mar 17 '11 at 23:00
  • Well, adding at the beginning should be faster on a Linked List, adding at the end should be just slightly faster with the Array List. – Argote Mar 17 '11 at 23:14
  • @Argote - nope. i've tried both now. either way, linkedlist was slower than arraylist. can you look at my code snippet above and make sure i didn't so something wrong? – user618712 Mar 17 '11 at 23:17
  • Well, as others have mentioned it would also depend on the amount of data in each list. A LinkedList has a higher overhead which is probably offset once the amount of elements that need to be relocated on an ArrayList exceeds certain threshold. – Argote Mar 17 '11 at 23:25
1

Why did you think LinkedList would be faster? In the general case, an insert into an array list is simply a case of updating the pointer for a single array cell (with O(1) random access). The LinkedList insert is also random access, but must allocate an "cell" object to hold the entry, and update a pair of pointers, as well as ultimately setting the reference to the object being inserted.

Of course, periodically the ArrayList's backing array may need to be resized (which won't be the case if it was chosen with a large enough initial capacity), but since the array grows exponentially the amortized cost will be low, and is bounded by O(lg n) complexity.

Simply put - inserts into array lists are much simpler and therefore much faster overall.

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
  • Well if we define "insert" as adding an element at a arbitrary position in the collection (which is imho the default definition) than you'd have to move all elements after the position. I'd first tip on a flawed benchmark.. – Voo Mar 17 '11 at 23:03
1

Linked list may be slower than array list in these cases for a few reasons. If you are inserting into the end of the list, it is likely that the array list has this space already allocated. The underlying array is usually increased in large chunks, because this is a very time-consuming process. So, in most cases, to add an element in the back requires only sticking in a reference, whereas the linked list needs the creation of a node. Adding in the front and the middle should give different performance in for both types of list.

Linear traversal of the list will always be faster in an array based list because it must only traverse the array normally. This requires one dereferencing operation per cell. In the linked list, the nodes of the list must also be dereferenced, taking double the amount of time.

Zoe
  • 1,833
  • 1
  • 16
  • 18
0

ArrayList is faster in accessing random index data, but slower when inserting elements in the middle of the list, because using linked list you just have to change reference values. But in an array list you have to copy all elements after the inserted index, one index behind.

EDIT: Is not there a linkedlist implementation which keeps the last element in mind? Doing it this way would speed up inserting at the end using linked list.

Jakob Alexander Eichler
  • 2,988
  • 3
  • 33
  • 49
  • 1
    actually you can't randomly insert into a LinkedList either, in order to find the insertion point a traversal is necessary. – bestsss Mar 17 '11 at 23:06
  • keeping a reference to the last element brings appending down from O(n) to O(1), but will still not beat a dynamic array when doing a lot of appends. – Fred Foo Mar 18 '11 at 00:53