# if oder switch



## Eminent (7. Feb 2006)

Hi, 

ich hätte da mal ne allgemeine Frage!   

Was ist im allgmeinen schneller / performanter viele if-Anweisungen ala


```
if (....) {
}
if (....) {
}
if (....) {
}
if (....) {
}
if (....) {
}
if (....) {
}
if (....) {
}
if (....) {
}
```

oder ein größerer Switch-Block?

Hintergrund ist, wir haben eine Klasse hier bei uns, die vor int-Konstanten nur so überläuft (über 100 oder 200) und an Hand dieser Konstanten wird bisher in einer Switchanweilsung entschieden wie weiter verfahren werden soll. Ich würde das ganze jetzt gern umstellen und etwas dynamischer arbeiten, da es bis jetzt bei jedem neuen Fall auch immer eine neue Konstante gibt. Das ist meiner Meinung nach nicht so Sinn der Sache. Problem ist nur wir müssten dann von ints wechseln auf Strings, was dann ja dazu führt, dass wir kein switch mehr verwenden können. Deshalb meine Frage ...   

Danke schon jetzt für die Antworten.

Gruß
Eminent


----------



## AlArenal (7. Feb 2006)

Wenn, dann bitte if-else-if mit switch vergleichen 

Bei deiner Problemstellung würde ich lieber mal das grundsätzliche Klassen-/Anwendungsdesign hinterfragen. Da liegt nämlich eher der Hund begraben. Deine Eingangsfrage ist nur eine Folge davon...


----------



## Bleiglanz (7. Feb 2006)

switch ist schneller, weil "Sprungtabelle"

in Java5 würde ich Enums verwenden, und den Aktionsteil aus den switches / ifs als Methoden gleich zu der Konstante packen, ist schön schnell und die switches verschwinden ganz


```
interface Aktion {
    public void tuES();
}

enum Konstante implements Aktion {
    KON1 {
        public void tuES(){};
    },  
    KON2 {
        public void tuES(){};
    }
}
```
wär aber wohl ein grösseres Refactoring (dafür kannst du neue Konstanten dazu tun, ohne am übrigen Code was zu ändern)


----------



## Eminent (7. Feb 2006)

Bleiglanz hat gesagt.:
			
		

> switch ist schneller, weil "Sprungtabelle"
> 
> in Java5 würde ich Enums verwenden, und den Aktionsteil aus den switches / ifs als Methoden gleich zu der Konstante packen, ist schön schnell und die switches verschwinden ganz
> 
> ...



Also Java5 fällt schon mal weg, da bei uns das JDK / JRE 1.4.2_01 zwingend vorgeschrieben ist und das wird sich so schnell auch nicht ändern.

Auch eine komplette Überarbeitung des Konzepts ist nicht möglich. Grud ist, dass die jetzige Architektur innerhalb der letzten 6-8 Jahre gewachsen ist und in unserem Teilbereich (Kernanwendung) selbst kleinste Änderungen am grundsätzlichen Aufbau sehr schwer zu bewerkstelligen sind. Wenn eine Umstellung erfolgen sollte, dann müsste das ganze parallel zur Produktion erfolgen und dazu fehlen bei uns die Leute.

Durch das ganze wird uns wohl (zumindest für den Moment) nix anders übrig bleiben als es erstmal bei der Situation zu lassen, bis es mal möglich ist etwas zu ändern bzw. bis die Zeit dazu mal wäre.

Naja, zumindest weiß ich jetzt, dass Switch schon mal schneller ist als if ....   

Danke euch


----------



## Bleiglanz (7. Feb 2006)

in dem Fall würde ich trotzdem einen zentralen Dispatcher vorschlagen, ein switch lässt sich oft durch einen einfachen Lookup-Mechanismus ersetzen (der viel leichter wartbar ist, und dessen Inhalt sich leicht Unit-Testen lässt)


```
// statt
switch(x){.....}

// besser 
((Command)commandMap.get(Integer.valueOf(x))).tuEs();

// und die commandMap "nahe" bei den Kostanten
// befüllen
```

ist doch kacke, wenn man jedesmal 100 oder mehr case-Klauseln durchsehen muss?


----------



## AlArenal (7. Feb 2006)

@bleiglanz:

Dann hätte ich in deinem Fall statt 100 case oder if-else 100 Implementierungen von Command?

Interessanter Ansatz.. *imhinterkopfbehalt*


----------



## Bleiglanz (7. Feb 2006)

> Dann hätte ich in deinem Fall statt 100 case oder if-else 100 Implementierungen von Command?


Ja, ist aber trotzdem besser wegen "Entkopplung"

Nur mal als Idee: man könnte z.B. 5 Kommandos die sehr ähnlich sind in eines packen und hätte dann da drin einen "kleineren switch"; oder ganz andere Gimmicks machen die dann den Rest des Codes nicht mehr stören...

Ausserdem hat so ein switch-statement mit 100 konstanten ja bestimmt 200 oder 300 Zeilen, und das ist eindeutig viel zuviel für eine einzige Methode, die hält das nicht lange aus!!


----------



## AlArenal (7. Feb 2006)

Stimme dir zu (jedenfalls wenn ich sso theoretisch überdenke) und werds bei nächster Gelegenheit mal in meine Designs einfließen lassen, wenn es sich anbietet.

Ich habe auch lieber mehr Klassen mit weniger Zeilen als weniger Klassen mit mehr Zeilen...


----------



## Eminent (7. Feb 2006)

Bleiglanz hat gesagt.:
			
		

> > Dann hätte ich in deinem Fall statt 100 case oder if-else 100 Implementierungen von Command?
> 
> 
> Ja, ist aber trotzdem besser wegen "Entkopplung"
> ...



Also wieviel Zeilen der switch-Block hat weiß ich nicht, aber die Klasse insgesamt sollte definitiv recht weit über 1200 Zeilen kommen. Ist ja auch mit ein Grund warum ich da evtl. was ändern möchte und ist leider nicht die einzige Klasse mit weit über 1000 Zeilen.

Wie dem auch sei, ich werd mir deinen Vorschlag mal genauer ansehen und mit meinem Kollegen absprechen ob man da nicht vielleicht was in die Richtung machen kann, wenn die nächsten größeren Projekte angstehen.

Danke euch!!!


----------



## SamHotte (7. Feb 2006)

@Bleiglanz:
Gibt es irgendwo eine Art Muster oder Anleitung, wie man das mit dieser Command-Map macht?


----------



## Sky (7. Feb 2006)

Die Idee ist ganz einfach:

Du hast eine "abstract class" oder ein Interface mit dem Namen "Command". Darin wird die Methode "tuEs" (oder was Du halt willst) definiert.

Dann gibt es konkrete "Command"-Klassen:


```
class CommandX implements Command {
  // ... method 'doIt' ...
}
```


```
class CommandY implements Command {
  // ... method 'doIt' ...
}
```

und dann bei deinen Konstanten:


```
final int x = 0;
final int y = 1;

commandMap.put( new Integer(x), new CommandX() );
commandMap.put( new Integer(y), new CommandY() );
```

diese kannst Du dann wie oben schon beschrieben aufrufen:

```
((Command)commandMap.get(Integer.valueOf(x))).doIt();
```


----------



## SamHotte (7. Feb 2006)

Aha. Und die int-Werte lege ich nach wie vor über entsprechde Konstanten fest, z. B. im Command-Interface, richtig? 
Demnach muss ich selbst dafür Sorge tragen, dass es keine zwei gleichen int-Werte für irgendwelche Commands gibt.


----------



## SlaterB (7. Feb 2006)

man muss immer für alles selber Sorge tragen aber kann natürlich auch eine entsprechende Operation zimmern, die das ganze überprüft

bei 100 Operationen gehen durchaus auch mal anonyme innere Klassen


----------



## Bleiglanz (7. Feb 2006)

tja, ein kleines Problem - die Map sollte sich am besten "automatisch auffüllen", ohne dass man irgendwas machen muss 

ansonsten besteht wie bei einer vergessenen switch-case-Klausel die Gefahr, dass man einen vergisst :-(

da kann man die tollsten Sachen drumherum Programmieren...


(aber wie gesagt: in Java5 sind enums IMHO dafür ganz gut geeignet...)


----------



## Eminent (7. Feb 2006)

Bleiglanz hat gesagt.:
			
		

> tja, ein kleines Problem - die Map sollte sich am besten "automatisch auffüllen", ohne dass man irgendwas machen muss
> 
> ansonsten besteht wie bei einer vergessenen switch-case-Klausel die Gefahr, dass man einen vergisst :-(
> 
> ...



Werd mir das ganze daheim auch mal mit Java5 ansehen und vielleicht kann ich ja dann unsere obersten Chefs mit solchen Beispielen überzeugen, dass sich ein Umstieg auf Java5 auch für uns lohnen könnte!  :lol: 

Also, ich dank euch nochmal!!

Gruß
Eminent


----------



## Sky (7. Feb 2006)

Eminent hat gesagt.:
			
		

> Werd mir das ganze daheim auch mal mit Java5 ansehen und vielleicht kann ich ja dann unsere obersten Chefs mit solchen Beispielen überzeugen, dass sich ein Umstieg auf Java5 auch für uns lohnen könnte!  :lol:



Mit der Zeit gehen lohnt sich i.d.R. immer...


----------



## Eminent (8. Feb 2006)

Sky hat gesagt.:
			
		

> Eminent hat gesagt.:
> 
> 
> 
> ...



Das ist bei uns leichter gesagt als getan. Ich bin froh, dass wir wenigstens 1.4 haben und uns nicht mehr mit 1.3 rumärgern müssen!!  :bae:


----------



## Sky (8. Feb 2006)

Eminent hat gesagt.:
			
		

> Das ist bei uns leichter gesagt als getan. Ich bin froh, dass wir wenigstens 1.4 haben und uns nicht mehr mit 1.3 rumärgern müssen!!  :bae:



Ich kenn' das Problem. Es ging nur um die Argumentation ;-)

btw.: ich muss eines meiner Applets bis heute mit JAVA 1.2.2 proggen...


----------



## AlArenal (8. Feb 2006)

@Bleiglanz:

Übrigens kannte ich das doch schon. Ich hatte es nur nie den Einsatzzweck als Ersatz für viele switch im Kopf. Jeff Heer macht in seiner tollen prefuse Lib was ganz ähnliches, um das Verhalten von Graphen variabel gestalten zu lassen.
Dort gibt es ein Interface Action und z.B. eine Klasse ActionList, welche wiederum Action implementiert. Damit lassen sich dynamisch Verhaltensregeln (für Layout, Animation, ...) für einen Graphen festlegen...


----------



## Bleiglanz (8. Feb 2006)

BTW

javax.swing.Action
javax.swing.InputMap
javax.swing.ActionMap

ist das ganze mit Vollgas (InputMap ist noch eine Indirektions-Ebene mehr für die Tastatur), und zum lookup verwendet man einfach beliebige Strings


----------



## AlArenal (8. Feb 2006)

Wieder ein Beitrag zum Thema "The hidden gems of Java Foundation Classes"


----------



## norman (8. Feb 2006)

was spricht denn dafür, nicht auf java5 umzusteigen?


----------



## Sky (8. Feb 2006)

norman hat gesagt.:
			
		

> was spricht denn dafür, nicht auf java5 umzusteigen?


Der Kundenwunsch.


----------



## norman (8. Feb 2006)

Sky hat gesagt.:
			
		

> norman hat gesagt.:
> 
> 
> 
> ...


ach? ich meine, was für einen vorteil hat der kunde daraus? klar, jre5 muss nicht installiert werden; aber gibt es irgendwelche vorteile eines älteren jre's? sicherheitslücken in neuen versionen oder sowas?


----------



## Bleiglanz (8. Feb 2006)

Nein, es gibt keinerlei Vorteile bei den älteren Versionen; und die Umstellung auf Java5 scheint ziemlich problemlos

aber der normale Admin draussen an der Front der pfeift erstmal auf alles was nach "Neu" aussieht, gehört zum Berufsethos dass man erstmal JEDEN Wunsch irgendetwas zu installieren ablehnt

Ist aber verständlich, der wer muss es wohl ausbaden, wenn was schiefgeht?


----------



## norman (8. Feb 2006)

nach meinem Klick auf die "Zitieren"-Schaltfläche



> Information
> 
> Nur haben die Berechtigung, in diesem Forum auf Beiträge zu antworten.



whatever. 

>> P.S. wer Ironie sieht kann sie behalten <<
fand ich witzig.


[edit] funzt wieder [/edit]


----------



## AlArenal (8. Feb 2006)

Bleiglanz hat gesagt.:
			
		

> aber der normale Admin draussen an der Front der pfeift erstmal auf alles was nach "Neu" aussieht, gehört zum Berufsethos dass man erstmal JEDEN Wunsch irgendetwas zu installieren ablehnt
> 
> Ist aber verständlich, der wer muss es wohl ausbaden, wenn was schiefgeht?



Seltsam ist nur, dass das eben dieselben Fatzkes sind, die mal eben aus Jux und Dollerei konzernweit (also in der ganzen Welt) ein Update für Firewalls und Proxies fahren und du hast schon blutende Ohren, weil der Kunde nervt, weil die Anwendungen nicht mehr laufen - der bekommt nämlich selber nicht Bescheid. Die Standort-IT merkt Änderungen immer erst dann, wenn was nicht mehr geht und hat keine Möglichkeit nachzuvollziehen wer wann was wo geändert hat, oder Anforderungen zu kommunizieren.

Ich will ja keine Namen nennen, daher sage ich mal: Weltweit zweitgrößter Hersteller von petrochemischen Produkten.. war gestern noch in der Presse, weil man "nur" 25% Gewinnplus gemacht hatte.. die Armen...


----------



## Guest (8. Feb 2006)

AlArenal hat gesagt.:
			
		

> Bleiglanz hat gesagt.:
> 
> 
> 
> ...



Das hat bei uns nichts mit Administratoren zu tun, sondern mit der ganzen "Geschäftsstruktur". Namen nenne ich natürlich auch nicht, aber ich denke es reicht, wenn ich sage öffentliche Anstalt!


----------

