Linked List Benchmarking..

Published 5 January 5 12:40 AM | William

Hardly the most scientific based analysis - but it makes the point:

I've just started getting back into the 2.0 Framework and came across my old friend the linked list. The linked list was one of those data structures that was actually fun to program in C++, mainly because it was really cool and hyper efficient. Well, by using Generics, the LinkedList is now supported in the 2.0 Framework - and you'll probably want to forget that you ever knew of such a thing as the ArrayList:
Just check out the performance difference on something as small as this (and let there be no more arguments in favor of ambiguous typing):

DateTime now = DateTime.Now;

LinkedList<System.String> myList = new LinkedList<System.String>();
for (int x = 0; x < 10000; x++)
{
myList.AddHead(
"Bill");
myList.AddTail(
"Sahil");
myList.AddTail(
"KC");
myList.AddTail(
"Andy");
myList.RemoveTail();
myList.AddHead(
"Skicow");

}
TimeSpan tp = DateTime.Now - now;

MessageBox.Show(tp.ToString()); //.01000 seconds

DateTime now2 = DateTime.Now;
ArrayList al = new ArrayList();

for (int x = 0; x < 10000; x++)
{
al.Add(
"Bill");
al.Add(
"Sahil");
al.Add(
"KC");
al.Add(
"Andy");
al.RemoveAt(al.Count - 1);
al.Insert(0,
"Skicow");
}
TimeSpan tp2 = DateTime.Now - now2;
MessageBox.Show(tp2.ToString()); //.29 seconds
 
Now, here's the impressive part. Move the counter up to 20,000. You'll get .02 on the LinkedList but 2.2383 on the ArrayList

Bump the counter to 50,000 and you get .07 on the LinkedList and 22.93 on the ArrayList.

At 100,000 you get .14 on the LinkedList (just about exactly double) - With the ArrayList 2:14.333 seconds. Even if I adjust the ArrayList's constructor to accomdodate the 100,000 expected elements, the change is virtually indistinguishable.

  1,000
10,000
20,000
40,000
50,000
100,000
Linked List
0.001
0.01
0.02
0.12
0.7
0.14
ArrayList
0.001
0.36
2.283
10.81
22.93
2:14.3

Comments

# William said on January 5, 2005 1:29 AM:

But the List<T> is more efficient for value types :). It's also more efficient when you aren't changing the entire list (Insert(0,...)). I hope people don't start using LinkedLists for no reason -- use the right algorithm for the problem. Try changing the Insert at zero to Insert(al.Count - al.Count / 10, "value") and see.

Also, try switching the order in which you perform the tests, as the memory usage will change the outcome. Compiling with optimizations made some big gains for List<T> for me.

# William said on January 5, 2005 8:50 AM:

You must take also a snapshot of the memory. In the case of the Linked List you have 100K objects to be GC vs just one in the case of ArrayList.

The overall application performance in the case of Linked List, will suffer IMHO

# William said on January 5, 2005 9:04 AM:

Michael - Yes, I agree with you - noticed the same behavior. I think the ArrayList though, as cool as it is, is overused in the wrong conditions a lot of the time. The thing with the arraylist is that when you add something to it, it needs rebuilt each time doesn't it? I was thinking that's where the optimization comes from.

----

Panos:

I see what you're saying - will definitely take a look into the memory utilization and see what's happening there. If it forces more gc's or it eats up a ton more memory - that would definitely offset the performance increases I saw. I have a lot more testing to do with it - but think overall it's a good addition.

Thanks guys

Bill

# William said on January 5, 2005 10:50 AM:

Now try doing the same in C++ with the STL's std::List. Which even has sort built into it and see what the time's on that are. Use char* as the type in one and use std::string as the type in the other and see what you see as far as memory used and speed. The clr is very efficiant so I'd be curious to see what the differences are.

# William said on January 5, 2005 10:58 AM:

Hey Bill,

Wow this is quite amazing, shows generic power can do wonders.

We should also compare the Generic List<T> with Arraylist. Those two objects are very very similar barring the type conversions - and that in my view could make a big difference.

- SM

# William said on January 5, 2005 12:12 PM:

The array list is just that: an array. The array list just handles resizing of the array for you. So if you manipulate something at the beginning, yea, you have to redo the array.

Perhaps you want a CircularArrayList?

The number of objects for the LinkedList on a reference type should be 2N. For an arraylist, only N. For a List<T> on valuetypes, the List will be 1, while the LinkedList will be N. So that's definately something to consider.

Sahil, I tried List<T> and it didn't make a difference. Since string is a reference type, the code produced should be the same. Indeed, the JIT shares generic code for all reference type parameters for a type.



# William said on January 5, 2005 2:47 PM:

Michael can I see ur generic list<t> code with string .. my email addy is sahilmalik at google's mail . Thanks.

# William said on January 5, 2005 5:17 PM:

OK, I went and took a look at the source for List and ArrayList. ArrayList is twice the filesize, but I see that's because it's got a bunch of specialized (private) classes: SyncArrayList, FixedSizeArrayList, ReadOnlyArrayList, etc. Taking those out, ArrayList is a tad smaller than List.

Pretty much all the code (apart from the generics) is char-by-char the same. I'm guessing it was copy, paste, modify :). Oh, and it seems that the ArrayList members are virtual (to allow those private classes), while the List ones are not. Other than that, the perf should be nearly identical.

Search

This Blog

Tags

Community

Archives

News

  • William G Ryan William Ryan Bill Ryan W.G. Ryan Charles Mark Carroll Charles M Carroll
    My Blog Juice Microsoft MVP
    Bill Ryan W.G. Ryan William Ryan
    Cuckooz' MySpace Page View Bill Ryan's profile on LinkedIn
    My Profile on Twitter
    Please note that this is my personal blog and the opinions expressed are my own. Also, comment moderation is about one of the least important things in my life so please keep that in mind. I can't vouch for the authenticity of any of the posters so please don't hold me accountable. And whatever you do, don't pretend to be Noted Option Strict Off expert and AspFriend Charles Mark Carroll when you post. Doing so will lead him to become apoplectic and write absurd accusatory posts about me that are as coherent and thought out as they are factually correct. He does a stellar job proving his reputation is well deserved and he doesn't need any help from you making himself look foolish. If I have to listen to him banging his spoon off of his high chair one more time, I'm going to burst into flames so please don't make that happen!

    My other sites

    Cool Stuff

    Book Stuff

    Security

    ORM

    Data Access

    Funny Stuff

    Compact Framework Stuff

    Web Casts

    My KnowledgeBase Articles

    My MVP Profile

    Design Patterns

    Performance

    Debugging

    Remoting

    My Fellow Authors

    My Books

    LINQ

    Misc

    Speech

    Syndication

    Email Notifications