Test av ytelse med C# collections

Ytelse er et mye diskutert tema på nettet og det finnes en del artikler med testing av ulike måter å gjøre ting på. I denne artikkelen skriver jeg litt om en ytelsestest jeg selv har gjort for å sammenligne ulike måter å samle objekter på. Det er testet med List<>IList<>ArrayArrayListHashTable og Egen klasse som arver fra List

Alle testene er gjort med 3 operasjoner. Legge inn n antall objecter i samlingen, liste de ut vha foreach og liste ut vha loop. Resultatet av testen vil naturligvis variere litt fra hver gang testen kjøres, men det viser seg at i denne testen er det Array som stikker av med seieren.

Men forskjellene er små og det viktigste er at du bruker en collection som inneholder de metodene du trenger. Denne testen er definitivt ikke dekkende og burde også tatt med en rekke andre situasjoner der man ikke bare add’er data til en collection. Som sagt er behovet viktig her.

class Program
{
    static Company temp = null;

    static void Main(string[] args)
    {
        int numItems = 10000000;

        Console.WriteLine("Testing with " + numItems.ToString() + " items");
        
        Console.WriteLine("------------------------------");
        TestList(numItems);
        Console.WriteLine("------------------------------");
        TestIList(numItems);
        Console.WriteLine("------------------------------");
        TestArray(numItems);
        Console.WriteLine("------------------------------");
        TestArrayList(numItems);
        Console.WriteLine("------------------------------");
        TestCompanyList(numItems);
        Console.WriteLine("------------------------------");
        TestHashTable(numItems);
        Console.WriteLine("------------------------------");
        
        Console.WriteLine("Test finished");

        Console.ReadLine();
    }

    static void TestArrayList(int numItems)
    {
        Console.WriteLine("TestArrayList()");
        StopWatch.Restart();

        ArrayList items = new ArrayList();

        for (int i = 0; i < numItems; i++)
        {
            items.Add(new Company("987", "Firma AS"));
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        foreach (Company s in items)
            temp = s;
        Console.WriteLine("Foreach");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i] as Company;
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();
        

        Console.WriteLine("TestArrayList() finished");
        items.Clear();
    }

    static void TestIList(int numItems)
    {
        Console.WriteLine("TestIList()");
        StopWatch.Restart();

        IList items = new List();
        for (int i = 0; i < numItems; i++)
        {
            items.Add(new Company("987", "Firma AS"));
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        foreach (Company s in items)
            temp = s;
        Console.WriteLine("Foreach");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i];
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();
        

        Console.WriteLine("TestIList() finished");
        items.Clear();
    }

    static void TestList(int numItems)
    {
        Console.WriteLine("TestList()");
        StopWatch.Restart();

        List items = new List();
        for (int i = 0; i < numItems; i++)
        {
            items.Add(new Company("987", "Firma AS"));
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        foreach (Company s in items)
            temp = s;
        Console.WriteLine("Foreach");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i];
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();
        

        Console.WriteLine("TestList() finished");
        items.Clear();
    }

    static void TestArray(int numItems)
    {
        Console.WriteLine("TestArray()");
        StopWatch.Restart();

        Company[] items = new Company[numItems];
        for (int i = 0; i < numItems; i++)
        {
            items[i] = new Company("987", "Firma AS");
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        foreach (Company s in items)
            temp = s;
        Console.WriteLine("Foreach");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i];
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();
        
        Console.WriteLine("TestList() finished");
        items = null;
    }

    static void TestCompanyList(int numItems)
    {
        Console.WriteLine("TestCompanyList()");
        StopWatch.Restart();

        CompanyList items = new CompanyList();
        for (int i = 0; i < numItems; i++)
        {
            items.Add(new Company("987", "Firma AS"));
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        foreach (Company s in items)
            temp = s;
        Console.WriteLine("Foreach");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i];
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();
        

        Console.WriteLine("TestCompanyList() finished");
        items.Clear();
    }

    static void TestHashTable(int numItems)
    {
        Console.WriteLine("TestHashTable()");
        StopWatch.Restart();

        Hashtable items = new Hashtable();
        for (int i = 0; i < numItems; i++)
        {
            items.Add(i, new Company("987", "Firma AS"));
        }
        Console.WriteLine("Adding finished");
        StopWatch.WriteCurrentTime();
        StopWatch.Restart();

        // NOT SUPPORTED
        //foreach (Company s in items)
        //    temp = s;
        //Console.WriteLine("Foreach");
        //StopWatch.WriteCurrentTime();
        //StopWatch.Restart();

        for (int i = 0; i < numItems; i++)
        {
            temp = items[i] as Company;
        }
        Console.WriteLine("Loop");
        StopWatch.WriteCurrentTime();


        Console.WriteLine("TestHashTable() finished");
        items.Clear();
    }

    public class CompanyList : List
    {   
    }

    public class Company
    {
        public Company(string orgnr, string name)
        {
            this.OrgNr = orgnr;
            this.Name = name;
        }

        public string OrgNr { get; set; }
        public string Name { get; set; }
    }

    #region # StopWatch #
    public class StopWatch
    {
        private static int startExecute = 0;
        private static int endExecute = 0;

        public static void Start()
        {
            startExecute = Environment.TickCount;
        }

        public static void Restart()
        {
            startExecute = Environment.TickCount;
            endExecute = 0;
        }

        public static double CurrentTime()
        {
            endExecute = Environment.TickCount;
            return (double)(endExecute - startExecute) / 1000.0;
        }

        public static void WriteCurrentTime()
        {
            Console.WriteLine("SW: " + CurrentTime().ToString());
        }
    }
    #endregion
}