Array gleiche werte abfragen

Arrays sind Grundstrukturen, aber wirklich oft brauchen tut man sie heute im Vergleich zu Auflistungen (und IEnumerable bei LINQ) nicht mehr so oft.

Hier könnten sie noch mal glänzen - unter der Voraussetzung die Zahl der möglichen Zufallswerte ist vorher bekannt:

        public static void RandomArrayCounter()
        {
            const int MaxValue = 20;

            Random rnd = new Random();
            // damit es (hier) wenigsten (meistens) 0 - 5 ms sind ;-)
            int[] intArray = Enumerable.Range(0, 100000).Select(i => rnd.Next(MaxValue)).ToArray();


            var sw = Stopwatch.StartNew();
            var groupby = new int[MaxValue];
            foreach (var key in intArray)
                groupby[key] = groupby[key] + 1;
            sw.Stop();

            var sw2 = Stopwatch.StartNew();
            Dictionary<int, int> groupby2 = new Dictionary<int, int>();
            foreach (var key in intArray)
            {
                int count = 0;
                if (groupby2.TryGetValue(key, out count))
                    groupby2[key] = count + 1;
                else
                    groupby2.Add(key, 1);
            }
            sw2.Stop();

            var sw3 = Stopwatch.StartNew();
            var groupby3 = intArray
                .GroupBy(value => value)
                .Select(group => new { Key = group.Key, Value = group.Count() })
                .OrderBy(group => group.Key)
                .ToArray();
            sw3.Stop();

/*          // Langweilig...
            foreach (var item in groupby2)
            {
                Console.WriteLine("Zahl: {0}, Anzahl: {1}", item.Key, item.Value);
            }
 */
            var msg = string.Format("Array: {0} ms, Dictionary: {1} ms, LINQ: {2} ms",
                sw.ElapsedMilliseconds, sw2.ElapsedMilliseconds, sw3.ElapsedMilliseconds);
            Console.WriteLine(msg);
            // MessageBox.Show(msg);
        }
Ich habe Frederics Beispiel ein klein wenig optimiert, damit ein Zugriff auf das Dictionary entfallen kann wegen:
anz[i]++; // => anz[i] = anz[i] + 1;

Aber die LINQ Variante hält sich immer noch ganz gut (und ließe sich leichter modifizieren).

Aber nur mit (drastisch) erhöhten Zahlen gibt es hier überhaupt (sehr wenig) zu messen (und der Test-Rechner hat 4 Jahre auf dem Buckel).

Messen sollte man keine Bildschirm-Ausgaben - dafür würde hier ein Vielfaches an Zeit verbraucht - und Vorbereitungen - wie hier das Erstellen des Zufall-Arrays - lässt man besser auch raus.

Tunlichst sollte man den ersten Durchlauf "vergessen"; dort kostet das Jitten (übersetzen) ein Gutteil Zeit.

Wie heißt es so schön: Wer misst misst Mist ;-))

Gruß Elmar

Hallo,

Arrays sind Grundstrukturen, aber wirklich oft brauchen tut man sie heute im Vergleich zu Auflistungen (und IEnumerable bei LINQ) nicht mehr so oft.

Hier könnten sie noch mal glänzen - unter der Voraussetzung die Zahl der möglichen Zufallswerte ist vorher bekannt:

        public static void RandomArrayCounter()
        {
            const int MaxValue = 20;

            Random rnd = new Random();
            // damit es (hier) wenigsten (meistens) 0 - 5 ms sind ;-)
            int[] intArray = Enumerable.Range(0, 100000).Select(i => rnd.Next(MaxValue)).ToArray();


            var sw = Stopwatch.StartNew();
            var groupby = new int[MaxValue];
            foreach (var key in intArray)
                groupby[key] = groupby[key] + 1;
            sw.Stop();

            var sw2 = Stopwatch.StartNew();
            Dictionary<int, int> groupby2 = new Dictionary<int, int>();
            foreach (var key in intArray)
            {
                int count = 0;
                if (groupby2.TryGetValue(key, out count))
                    groupby2[key] = count + 1;
                else
                    groupby2.Add(key, 1);
            }
            sw2.Stop();

            var sw3 = Stopwatch.StartNew();
            var groupby3 = intArray
                .GroupBy(value => value)
                .Select(group => new { Key = group.Key, Value = group.Count() })
                .OrderBy(group => group.Key)
                .ToArray();
            sw3.Stop();

/*          // Langweilig...
            foreach (var item in groupby2)
            {
                Console.WriteLine("Zahl: {0}, Anzahl: {1}", item.Key, item.Value);
            }
 */
            var msg = string.Format("Array: {0} ms, Dictionary: {1} ms, LINQ: {2} ms",
                sw.ElapsedMilliseconds, sw2.ElapsedMilliseconds, sw3.ElapsedMilliseconds);
            Console.WriteLine(msg);
            // MessageBox.Show(msg);
        }
Ich habe Frederics Beispiel ein klein wenig optimiert, damit ein Zugriff auf das Dictionary entfallen kann wegen:
anz[i]++; // => anz[i] = anz[i] + 1;

Aber die LINQ Variante hält sich immer noch ganz gut (und ließe sich leichter modifizieren).

Aber nur mit (drastisch) erhöhten Zahlen gibt es hier überhaupt (sehr wenig) zu messen (und der Test-Rechner hat 4 Jahre auf dem Buckel).

Messen sollte man keine Bildschirm-Ausgaben - dafür würde hier ein Vielfaches an Zeit verbraucht - und Vorbereitungen - wie hier das Erstellen des Zufall-Arrays - lässt man besser auch raus.

Tunlichst sollte man den ersten Durchlauf "vergessen"; dort kostet das Jitten (übersetzen) ein Gutteil Zeit.

Wie heißt es so schön: Wer misst misst Mist ;-))

Gruß Elmar

Hey und sorry wenn ich mich hier mal einklinke... Ich mache grade ne ausbildung zum Anwendungsentwickler und habe eigentlich fast genau dieselbe aufgaabe bekommen... (nur mit chars) Ich habe es dann mit einer einfachen linqmethode getan (array.sort soll ich nicht verwenden)

Das ist meinem ausbilder leider immernoch zuviel was vom Programm selbst gemacht wird und er hat mir die aufgabe gestellt das array nur mit for, foreach und whileschleifen zu sortieren... Leider hackts da jetzt irgendwie total bei mir :( Kann mir jemand einen Denkanstoß geben ( bitte keinen kompletten Quelltext, ich will das ja lernen :))