Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. IList vs array performance observation (.NET 2.0)

IList vs array performance observation (.NET 2.0)

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharpvisual-studiodata-structurestestingbeta-testing
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wout de zeeuw
    wrote on last edited by
    #1

    I was wanted to share some performance observations after fiddling around with arrays and IList<type>. Since e.g. a double[] a array automatically implements IList<double> in .NET 2.0 I can conveniently accept IList<double> as argument for any method without also needing an overload for double[]. However, after some quick testing it seems a performance penalty is involved using the IList interface! I used this small program to compare the options: using System; using System.Collections.Generic; using System.Text; namespace TestListVsArray { class Program { static void Main(string[] args) { double[] a = new double[10000]; for (int i = 0; i < 3; i++) { TestA(a); TestB(a); TestC(a); TestD(a); Console.WriteLine(); } } private static void TestA(IList a) { DateTime start = DateTime.Now; double x = 0d; for (int j = 0; j < 1000; j++) { for (int i = 0; i < a.Count; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestB(IList a) { DateTime start = DateTime.Now; double x = 0d; int n = a.Count; for (int j = 0; j < 1000; j++) { for (int i = 0; i < n; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestC(double[] a) { DateTime start = DateTime.Now; double x = 0d; for (int j = 0; j < 1000; j++) { for (int i = 0; i < a.Length; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestD(double[] a) { DateTime start = DateTime.Now; double x = 0d; int n = a.Length; for (int j = 0; j < 1000; j++) { for (int i = 0; i < n; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } } } Output on my machine was

    R 1 Reply Last reply
    0
    • W wout de zeeuw

      I was wanted to share some performance observations after fiddling around with arrays and IList<type>. Since e.g. a double[] a array automatically implements IList<double> in .NET 2.0 I can conveniently accept IList<double> as argument for any method without also needing an overload for double[]. However, after some quick testing it seems a performance penalty is involved using the IList interface! I used this small program to compare the options: using System; using System.Collections.Generic; using System.Text; namespace TestListVsArray { class Program { static void Main(string[] args) { double[] a = new double[10000]; for (int i = 0; i < 3; i++) { TestA(a); TestB(a); TestC(a); TestD(a); Console.WriteLine(); } } private static void TestA(IList a) { DateTime start = DateTime.Now; double x = 0d; for (int j = 0; j < 1000; j++) { for (int i = 0; i < a.Count; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestB(IList a) { DateTime start = DateTime.Now; double x = 0d; int n = a.Count; for (int j = 0; j < 1000; j++) { for (int i = 0; i < n; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestC(double[] a) { DateTime start = DateTime.Now; double x = 0d; for (int j = 0; j < 1000; j++) { for (int i = 0; i < a.Length; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } private static void TestD(double[] a) { DateTime start = DateTime.Now; double x = 0d; int n = a.Length; for (int j = 0; j < 1000; j++) { for (int i = 0; i < n; i++) { x += a[i]; } } Console.WriteLine("{0}, {1}", DateTime.Now - start, x); } } } Output on my machine was

      R Offline
      R Offline
      ricardojb
      wrote on last edited by
      #2

      Of course there will be a performance penalty for using a collection over an array. Even though with generics you can easily implement strongy typed collections (avoiding casting and boxing unboxing), the collections in fact use arrays. They provide you with more flexibility than an array (like you don't need to know the number of elements and they can grow as needed) but basically what it does is array operations. There are some ways you can improve performance, if you know the number of items you can setup the MaximumLenght property of your collection. Also, both with arrays and collections, whenever you try to access a member, the CLR will perform a bound check. but if you access it in a for loop, where you expressely use the .Count, or .Lenght property, the compiler is smart enough to detect that and won't do bound checks with a considerable performance gain (in long running loops). for example suppose you have an array a and you want to iteract. you can do it like this: int limit = a.Lenght; for (int i = 0; i < limit; i++) { } this will do a bound check for each iteraction. if you do for (int i=0; i < a.Lenght; i++) { } this boundcheck will not be performed.

      W 1 Reply Last reply
      0
      • R ricardojb

        Of course there will be a performance penalty for using a collection over an array. Even though with generics you can easily implement strongy typed collections (avoiding casting and boxing unboxing), the collections in fact use arrays. They provide you with more flexibility than an array (like you don't need to know the number of elements and they can grow as needed) but basically what it does is array operations. There are some ways you can improve performance, if you know the number of items you can setup the MaximumLenght property of your collection. Also, both with arrays and collections, whenever you try to access a member, the CLR will perform a bound check. but if you access it in a for loop, where you expressely use the .Count, or .Lenght property, the compiler is smart enough to detect that and won't do bound checks with a considerable performance gain (in long running loops). for example suppose you have an array a and you want to iteract. you can do it like this: int limit = a.Lenght; for (int i = 0; i < limit; i++) { } this will do a bound check for each iteraction. if you do for (int i=0; i < a.Lenght; i++) { } this boundcheck will not be performed.

        W Offline
        W Offline
        wout de zeeuw
        wrote on last edited by
        #3

        The point is that I'm using a typesafe array in any case, not one of the collection flavors. I was just testing out which interface to the typesafe array was quickest. I would have hoped the difference between normal array access and access through IList<double> was minimal, but apparantly it isn't. :^) Also there seems no performance difference in practise between doing (see measurement results above): int limit = a.Lenght; for (int i = 0; i < limit; i++) { } and for (int i=0; i < a.Lenght; i++) { } Maybe the compiler is smart enough here to optimize the limit variable away... Wout

        E 1 Reply Last reply
        0
        • W wout de zeeuw

          The point is that I'm using a typesafe array in any case, not one of the collection flavors. I was just testing out which interface to the typesafe array was quickest. I would have hoped the difference between normal array access and access through IList<double> was minimal, but apparantly it isn't. :^) Also there seems no performance difference in practise between doing (see measurement results above): int limit = a.Lenght; for (int i = 0; i < limit; i++) { } and for (int i=0; i < a.Lenght; i++) { } Maybe the compiler is smart enough here to optimize the limit variable away... Wout

          E Offline
          E Offline
          Ed Poore
          wrote on last edited by
          #4

          wout de zeeuw wrote:

          Maybe the compiler is smart enough here to optimize the limit variable away...

          I'm not 100% sure but can't a.Length change inside the loop? So therefore the compiler can't optimize it unless it analyses the whole loop, and I'm guessing that the problems that could occur if it did would outweight the speed advantage. Ed

          W 1 Reply Last reply
          0
          • E Ed Poore

            wout de zeeuw wrote:

            Maybe the compiler is smart enough here to optimize the limit variable away...

            I'm not 100% sure but can't a.Length change inside the loop? So therefore the compiler can't optimize it unless it analyses the whole loop, and I'm guessing that the problems that could occur if it did would outweight the speed advantage. Ed

            W Offline
            W Offline
            wout de zeeuw
            wrote on last edited by
            #5

            It can indeed (just tested :-))! So beats me why the two options are equally fast. Wout

            E 1 Reply Last reply
            0
            • W wout de zeeuw

              It can indeed (just tested :-))! So beats me why the two options are equally fast. Wout

              E Offline
              E Offline
              Ed Poore
              wrote on last edited by
              #6

              Because they're both accessing the same type of variable. The a.Length one is simply a property wrapper around an int so in effect they're doing the same thing and hopefully JIT will optimize away the property call if it's just a wrapper, but I'm not so sure :rolleyes: Ed

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups