Laden...

Switch mit sehr vielen case blöcken?

Erstellt von michaelm vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.520 Views
M
michaelm Themenstarter:in
4 Beiträge seit 2008
vor 16 Jahren
Switch mit sehr vielen case blöcken?

Ich habe eine Methode die mehrmals hintereinander aufgerufen wird. Das Problem ist das dabei ein zuvor berechneter int Wert übergeben wird welcher zwischen 1 und 100 liegt und für jede Zahl eine individuelle Abhandlung notwendig ist. Soweit wie wir das gelernt haben ist ein case im switch equivalent zum else if. Wenn ich der Methode nun einen Wert von 100 übergebe, würde 99 mal eine els if Überprüfung erfolgen. Gibt es hierzu irgendeine Alternative also so das ein direkter Sprung zur korrekten Position erfolgt?

343 Beiträge seit 2007
vor 16 Jahren

Wenn du C programmieren würdest, wärs recht einfach 😉

Theoretisch ist es schon möglich:
1.) Erstelle ein Interface (oder abstrakte Klasse) (A) mit einer Funktion (run) und 100 Klassen, die dieses Interface implementieren (von dieser Klasse abgeleitet sind) und alle die Funktion run implementieren.

2.) Dann nimmst du ein Array oder eine List<A> und speicherst in jedes Element ein Objekt einer Klasse. Über den Index könntest du dann direkt an die Stelle (und den richtigen Code springen).

Eventuell lässt sich das ganze auch einfacher machen z.B. mit delegates, mit der oberen Variante würds auf jeden Fall klappen.
Einen merkbaren Performancevorteil würde dir das natürlich nicht verschaffen (wenn du darauf aus bist), da ja auch C# intern prüfen muss um welches Objekt es sich handelt und welcher Code nun ausgeführt werden soll.

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
1.378 Beiträge seit 2006
vor 16 Jahren

Unabhängig davon ob es Sinn macht,kannst du ja vorab entscheiden wo du einsteigen willst bei deiner if-else abfrage.

Bsp:


void SwitchTest(int num){
  if(num < 50){
    if(num < 25){
      //etc
    }
    else{
      //etc
    }
  }
  else{
    if(num < 75){
      //etc
    }
    else{
      //etc
    }
  }
}

Weiß zwar nicht ob sich der Aufwand lohnt, aber schneller ists vermutlich als von 0-99 durch zu testen.

Lg XXX

/Edit: Delegates in einem Array würd ich auch als vernünftige Alternative sehen.

343 Beiträge seit 2007
vor 16 Jahren

Ach ja, wenn du wirklich 100 Werte (ohne Unterbrechnung) hast bin ich mir doch recht sicher, dass ein switch schneller ist als if else.
Hier gibt es einen interessanten Artikel über das switch-Statement in C# und wie die Performance davon aussieht: http://weblogs.asp.net/justin_rogers/archive/2004/03/25/95806.aspx
Ist zwar in Englisch, aber das Lesen lohnt sich.

Lg
Preli

//edit: wenn es dir nur um Performance geht, ist der Vorschlag von xxxprod sicher seeehr empfehlenswert.

[- www.saftware.net -](http://www.saftware.net/)
M
michaelm Themenstarter:in
4 Beiträge seit 2008
vor 16 Jahren

Wenn du C programmieren würdest, wärs recht einfach 😉

Ja, das wäre endlich eine sinvolle Anwendung für goto. 😁

wenn es dir nur um Performance geht, ist der Vorschlag von xxxprod sicher seeehr empfehlenswert.

Ja, der ganze Aufbau ist eigentlich nur wegen Performance gründen so entstanden.

Ich werde es in dem Fall einmal mit dem von xxxprod vorgeschlagenen Delegates in Array testen. Erscheint mir noch am ehesten dem zu entsprechen was ich wollte. Danke soweit einmal für die schnellen Antworten.

343 Beiträge seit 2007
vor 16 Jahren

Ja, das wäre endlich eine sinvolle Anwendung für goto. 😁 Hätte da eher an Functionpointer gedacht. goto ist finde ich nicht mal für C empfohlen, dass ist eher was für Assembler.

Ich werde es in dem Fall einmal mit dem von xxxprod vorgeschlagenen Delegates in Array testen.

Nun das mit den delegates hab ich eigentlich auch vorgeschlagen. Ich denke um zu wissen was Performancemäßig besser ist müsste man fast beides austesten -> if-Lösung von xxxprod und delegates in Arrays.
Ich glaube dass beide Varianten recht flott sein sollten.
Aber einen Unterschied wirst du ohnehin nur merken wenn du die Funktion sehr, sehr oft aufrufst.

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
4.207 Beiträge seit 2003
vor 16 Jahren

Erstell Dir ein Dictionary<int, delegate> und pack als Key die Zahlen von 1 bis 100 rein und als Value einen Delegate, der auf den entsprechenden Code verweist. Dann kannst Du über den Key zugreifen, der Code wird kompakter, und vor allem schneller ...

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

343 Beiträge seit 2007
vor 16 Jahren

Ich denke wenn es wirklich die Zahlen 1-100 gibt ist ein Dictionary<int, delegate> überflüssig. List<delegate> wäre besser geeignet. Dictionary ist zwar schnell, aber warum soll man den Computer die richtige Position "suchen" lassen wenn man per Index direkt darauf zugreifen kann.
Mit Dictionary ist es zwar sehr schön gelöst, aber ich vermute dass List<delegate> schneller ist.

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
4.207 Beiträge seit 2003
vor 16 Jahren

Dictionary hat beim lesenden Zugriff fast O(1), da es intern eine Hashtable verwendet ... siehe MSDN: Dictionary<TKey, TValue> Class ...

Viel schneller geht's nicht.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

343 Beiträge seit 2007
vor 16 Jahren

List<delegate> hat auch O(1) wenn du direkt mit Index drauf zugreifst

Lg
Preli

[- www.saftware.net -](http://www.saftware.net/)
49.485 Beiträge seit 2005
vor 16 Jahren

Hallo michaelm,

Soweit wie wir das gelernt haben ist ein case im switch equivalent zum else if.

funktional schon, aber gerade nicht, was die Performance angeht. Der Vorteil von switch ist, dass die Labes direkt angesprungen werden können. Daher ist es grundsätzlich möglich, dass ein switch quasi nur einen Vergleich macht und dann sofort zum richtigen Label springt. Jedenfalls wenn der Compiler schlau genug ist.

Wenn ja, dann kann man sich natürlich alle Hilfskonstruktionen mit Dictionary oder List sparen.

herbivore

4.207 Beiträge seit 2003
vor 16 Jahren

@ preli: Mein Hinweis auf O(1) bezog sich auf Deine Vermutung, dass List schneller sei, und das ist sie eben nicht. Sie ist auch nicht langsamer, aber letztlich ist es wurscht, welches von beiden Du nimmst ...

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

343 Beiträge seit 2007
vor 16 Jahren

Es ist nicht ganz wurscht welche man nimmt, denn O(1) ist nicht gleich O(1)
//edit: scheinbar doch

Hab mal einen kleinen Test gemacht:


            List<string> list = new List<string>(100);
            Dictionary<int, string> dict = new Dictionary<int, string>(100);
            for (int i = 0; i < 100; i++)
            {
                list.Add(i.ToString());
                dict[i] = i.ToString();
            }

            Random r = new Random();

            for (int l = 0; l < AMOUNT; l++)
            {
                temp = list[r.Next(0, 99)];
            }

            for (int d = 0; d < AMOUNT; d++)
            {
                temp = dict[r.Next(0, 99)];
            }

//edit: hab mich vertan, ist doch ziemlich gleich schnell - mea culpa.

Dann würd ich fast auch zu dictionary raten 😉 (ist "schöner")

[- www.saftware.net -](http://www.saftware.net/)
4.207 Beiträge seit 2003
vor 16 Jahren

Okay, danke für die Aufklärung 🙂

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Golo Roden,

auch wenn die Größenordnung gleich ist: Ein Listenzugriff per Index ist schon schneller als ein Dictionary-Zugriff per Key. Und da hier die Indexwerte auch noch dicht liegen und bei nahe Null beginnen, wäre eine Liste hier einem Dictionary klar vorzuziehen ... allerdings nur, wenn der Compiler nicht schlau genug ist, das mit dem switch intelligent hinzubekommen. Wenn er es nämlich ist - wovon ich eigentlich ausgehe - dann sollte man natürlich auf die Hilfskonstruktionen ganz verzichten.

herbivore