if vs. switch

Devil0s

Aktives Mitglied
Kann mir jemand sagen was schneller ist? Ein verschachteltes if in der Form:
Java:
if(a < 1024){
	if(a < 512) {
		if(a < 256) {
			usw....
		}
	}
}

oder ein switch mit 1024 verschiedenen cases.

Also ein 10 mal verschachteltes if oder ein switch mit 1024 cases?
 
Zuletzt bearbeitet:
G

Gast2

Gast
Ich geh mal davon aus dass es dir völlig egal sein kann was schneller ist. Du wirst den unterschied nicht merken.

Würdest du uns mal verraten wofür du so ein obskures Konstrukt brauchst?
 

Devil0s

Aktives Mitglied
Es soll eine id zugewiesen werden und dann je nachdem welche id es ist soll ein bestimmtes Object erzeugt werden.
Das sollte fuer eine Art Spiel genommen werden. D.h. dieser Code sollte in regelmaessigen Abstaenden wiederholt werden.
 
G

Gast2

Gast
Das war ja nicht die Frage. Referenziert eine Id immer genau auf ein zu erstellendes Objekt?

Gib doch mal nen Beispiel was die Eingabe ist und was dann passieren soll.
 

Devil0s

Aktives Mitglied
Vielleicht. eigentlich nicht unbedingt, aber das limit sollte 1024 sein.
Ich bin ja froh wenn es 20 verschiedene gibt...
 

DrZoidberg

Top Contributor
Wieso überhaupt ein Limit einbauen?
Du kannst doch schreiben
Java:
public Gegner neuerGegner(int id) {
    switch(id) {
        case 1: return new Kaefer();
        case 2: return new Zombie();
        usw.
    }
}
 
Zuletzt bearbeitet:
G

Gast2

Gast
Ich würde dafür wie schon gesagt ne Map verwenden. Darin würde ich dann entweder das Klassenobjekt oder eine Factory legen. Entscheidest du dich für ersteres musst du etwas mit Reflection rumtricksen.
 

Devil0s

Aktives Mitglied
Sieht gut aus, aber ist das auch wirklich schnell? Das wird sehr oft aufgerufen werden.
Vielleicht hat Eike hat noch ne bessere/effizientere Variante.

EDIT: Zu spaet. Eike hat schon geantwortet.
 
Zuletzt bearbeitet:
T

tröööt

Gast
ich glaube im vorliegenden fall zählt das wohl eher unter micro-benchmarking und -optimierung ...

wenn also ID 1 immer einen zombie referenzieren soll ... dann auf jeden fall ne map mit factories ...

also dann sowas

((ZombieFactory)map.get(1)).generateZombie()

geht natürlich mit interfaces noch etwas eleganter ... aber ich glaube es dürfte sich nicht viel nehmen ...

zu mal "verschachteltes" if() hier eh eher weniger angebracht wäre ... auch mit verschiedenen "oberklassen"
 
J

JohannisderKaeufer

Gast
Das ganze ließe sich auch ohne if, switch oder den expliziten Einsatz von Maps regeln, wenn man Enums nutzt.

In einem Enum kann man Factories bereithalten, die die Gegner erstellen.
Java:
public enum GegnerProvider {
    KAEFER_PV {
        Gegner createGegner() {
            System.out.printf("Creating Enemy with %s%n",name());
            return new Gegner() {
            };
        }
    }, ZOMBIE_PV {
        Gegner createGegner() {
            System.out.printf("Creating Enemy with %s%n",name());
            return new Gegner() {
            };
        }
    }, ALIEN_PV {
        Gegner createGegner() {
            System.out.printf("Creating Enemy with %s%n",name());
            return new Gegner() {
            };
        }
    };

    abstract Gegner createGegner();
}

Und beim verwenden, kann man dann auf verschiedene Arten auf die Factories zugreifen.
Java:
public class Game {

    public void play(){
        Gegner kaefer = GegnerProvider.values()[0].createGegner();
        Gegner zombie = GegnerProvider.ZOMBIE_PV.createGegner();
        Gegner alien = GegnerProvider.valueOf("ALIEN_PV").createGegner();
    }

    public static void main(String[] args){
        new Game().play();
    }
}

Über den Index, über die Factory direkt oder über einen eindeutigen Namen.

Statt einer Map wie es Herr tröööt vorgeschlagen hat, kann man in dem Fall auch ein einfaches array nehmen
Java:
GegnerFactory dieBrueterei = {new ZombieFactory(), new AlienFactory()};
dieBrueterei[id].createGegner();
 

Network

Top Contributor
Switch und If sind ein und derselbe Code nur anderst aufgeschrieben.
Switch wurde eingeführt um die Daten anderst darstellen zu können und dem Programmierer unter umständen das lesen des Codes zu erleichtern.

Lass dich nicht von dem "break;" in Switch in die Irre führen, auch das existiert in einer if-Abfrage. Es wird nur nicht dargestellt sondern vom Compiler hinzugefügt.


Eine if/switch Fallabfrage der ID ist der schnellste Weg von Allen.
Schneller als irgendwelche Mengen (HashMaps) oder Listen zu verwenden.

Mein erster Gedanke war, dass HashMaps im Code vieleicht schöner und flexibler sind, aber das stimmt ja eigentlich überhaupt nicht. In beiden Fällen müssen die Daten einzeln von Hand eingetragen werden und für die HashMap müssen sogar noch extra Factory-Klassen geschrieben werden.
Eigentlich ist damit eine Switch-Abfrage nicht nur schneller sondern sogar noch viel flexibler als eine HashMap.
 

ARadauer

Top Contributor
@JohannisderKaeufer ich finde das ist eine sehr schöne Lösung... jedoch hab ich immer das Problem bei Enums, dass man sie nicht erweitern kann. Du bringst keine neuen Gegner Arten rein ohne das du diese Klasse anpasst.

Das ist wahrscheinlich oft kein Problem, ich arbeite aber oft an Modulen, wo ich einfach eine gewisse Kernfunktionalität zur Verfügung stelle und ein anderes Produkt unserer Firma das verwendet und da irgendwelche neuen Fachlichkeiten einfügen muss... seis jetzt ein neuer ZombiGegner oder irgend ein Kosten Positions Typ..
ich würds so jetzt konkret ungefähr so machen..

Java:
package gegner;

public interface GegnerFactory {
	
	Gegner createGegner();
	

}
Java:
package gegner;

public class Gegner {

	private String name;
	private int energy;
	private int hitPoints;

	public Gegner(String name, int energy, int hitPoints) {
		super();
		this.name = name;
		this.energy = energy;
		this.hitPoints = hitPoints;
	}

	@Override
	public String toString() {
		return "Gegner [name=" + name + ", energy=" + energy + ", hitPoints=" + hitPoints + "]";
	}

}
Java:
package gegner;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class GegnerProvider {
	
	Map<String, GegnerFactory> gegnerFactories = new HashMap<String, GegnerFactory>();
	
	public GegnerProvider(){
		gegnerFactories.put("ZOMBIE", new GegnerFactory() {			
			@Override
			public Gegner createGegner() {
				return new Gegner("Zombie", 10, 1);
			}
		});
		gegnerFactories.put("ZOMBIE_100", new GegnerFactory() {			
			@Override
			public Gegner createGegner() {
				return new Gegner("Zombie 100", 100, 5);
			}
		});
		gegnerFactories.put("ALIEN", new GegnerFactory() {			
			@Override
			public Gegner createGegner() {
				return new Gegner("Alien", 1000, 10);
			}
		});
	}
	
	public Gegner createGegner(String id){
		GegnerFactory factory = gegnerFactories.get(id);
		if(factory == null){
			throw new IllegalArgumentException("No Factory with ID "+id);
		}
		return factory.createGegner();
	}
	
	public Set<String> getPossibleIds(){
		return gegnerFactories.keySet();
	}
	
	public void addFactory(String id, GegnerFactory factory){
		if(gegnerFactories.get(id) != null){
			throw new IllegalArgumentException("Factory with "+id+" allready exists");
		}
		gegnerFactories.put(id, factory);
	}

}
Java:
package gegner;

public class Test {

	public static void main(String[] args) {
		GegnerProvider provider = new GegnerProvider();
		System.out.println(provider.createGegner("ZOMBIE"));
		System.out.println(provider.createGegner("ALIEN"));

		// habe später die Möglichkeit ohne meine Kern Anwendung zu verändern, 
		// neue Typen hinzuzufügen zb über irgend einen Plugin Mechanismus
		provider.addFactory("NEW_ENEMY", new GegnerFactory() {
			@Override
			public Gegner createGegner() {
				return new Gegner("neuer Gegner", 1, 1);
			}
		});

		System.out.println(provider.createGegner("NEW_ENEMY"));
	}

}

optimize later... ich denke nicht, das man durch ein if else, einen bedeutenden geschwindigkeits vorteil erreicht. schneller ist es auf jeden fall, aber ob man es schaft den vorteil zu messen das bezweifle ich...
 

langhaar!

Bekanntes Mitglied
Kann mir jemand sagen was schneller ist? Ein verschachteltes if [...]

oder ein switch

Wer sich ernsthaft solche Fragen stellt, für den ist Java die falsche Sprache.

Schon mal über C oder evtl. sogar Assembler nachgedacht?
(In Assembler kann man fleißig Takzyklen zählen und ein Maximim - bezogen auf alle Computersprachen - an Geschwindigkeit erzielen)
 
S

Spacerat

Gast
Also Enums sind schon mal 'ne Tolle Idee. Maps natürlich auch. Da Enums den Nachteil haben, dass sie sich nicht erweitern lassen, ohne die Klasse zu verändern, kann man ja ein Interface dafür preparieren. Allerdings benötigt man dann entweder wieder 'ne Map (IdentityHashMap) oder...
Java:
interface GameObjectType<E extends Enum<E>> {
  GameObject create();
}

enum TypeSetA implements GameObjectType<TypeSetA> {
	BUG(Bug.class),
	ZOMBIE(Zombie.class),
	;

	private final Class<? extends GameObject> clazz;

	private TypeSetA(Class<? extends GameObject> clazz) {
		this.clazz = clazz;
	}

	@Override
	public GameObject create() {
		try {
			return clazz.newInstance();
		} catch(ReflectiveOperationException e) {
			return null;
		}
	}
	
}

enum TypeSetB implements GameObjectType<TypeSetB> {
	CAT(Cat.class),
	DOG(Dog.class),
	;

	private final Class<? extends GameObject> clazz;

	private TypeSetB(Class<? extends GameObject> clazz) {
		this.clazz = clazz;
	}

	@Override
	public GameObject create() {
		try {
			return clazz.newInstance();
		} catch(ReflectiveOperationException e) {
			return null;
		}
	}
	
}

class GameObject {
}

class Zombie extends GameObject {
	
}

class Bug extends GameObject {
	
}

class Cat extends GameObject {
	
}

class Dog extends GameObject {
	
}
Das Erstellen neuer Objekte reduziert sich dann auf "GameObjectType<?>#create()", mit anderen Worten, die ID (die Klasse GameObjectType) selber würde das Objekt erstellen.
 

Noctarius

Top Contributor
Switch und If sind ein und derselbe Code nur anderst aufgeschrieben.
Switch wurde eingeführt um die Daten anderst darstellen zu können und dem Programmierer unter umständen das lesen des Codes zu erleichtern.

Das stimmt so nicht, da wird auch anderer Bytecode erzeugt, genau deswegen gingen ganz lange keine Strings in Switch-Blöcken.

Aber der Geschwindigkeitsunterschied ist minimal. Ich würde entweder eine Map nutzen und die ID als Key nehmen (dann könnte man die Daten auch aus einem externen File laden) oder wenn es hardcoded ist auf ein Enum setzen.
 
S

Spacerat

Gast
[OT]
Das stimmt so nicht, da wird auch anderer Bytecode erzeugt, genau deswegen gingen ganz lange keine Strings in Switch-Blöcken.
Stimmt, da ist was wahres dran. Switch funktioniert - im Hintergrund - eigentlich nur mit integralen Werten, vergleichbar mit Sprungtabellen in Assembler (Switch funktioniert deswegen auch nur mit Konstanten). Und jetzt wo du Strings in Switch erwähnst, frage ich mich, ob das der Grund ist, warum nun jeder nicht internalisierte String sein eigenes Chararray hat, weswegen es die Member offset und count auch nicht mehr gibt und für Switch nun die Startadresse dieses Arrays verwendet wird. Ferner frage ich mich, wieso hat man dann nur Strings ermöglicht und nicht auch noch gleich andere Immutables (ausser die Wrapperklassen). In Assembler funktionieren Sprungtabellen mit jeder Art von Objekt, aber das ist erstens eh' 'ne ganz andere Liga und in Java immerhin emulierbar.[/OT]
 

Noctarius

Top Contributor
[OT]Die Strings werden intern über deren Hashcode verglichen und damit in der Switch-Lookup-Table vorgehalten. Aber ja, theoretisch lassen sich damit auch andere Dinge bauen, ich hätte mir z.B. eine TypeOf-Switch gewünscht :)[/OT]
 
H

hüteüberhüte

Gast
Kann mir jemand sagen was schneller ist? Ein verschachteltes if in der Form:
Java:
if(a < 1024){
	if(a < 512) {
		if(a < 256) {
			usw....
		}
	}
}

oder ein switch mit 1024 verschiedenen cases.

Also ein 10 mal verschachteltes if oder ein switch mit 1024 cases?

switch macht intern so etwas wie ==. Das wären 1024 ==-Ifs. Deshalb wären ~ 10 Ifs schneller.
 

OlliL

Bekanntes Mitglied
Die Frage zu stellen ist schon der falsche Weg ;)

Erstmal Gedanken machen, wie du einen wartbaren und sauberen Code hinbekommst.
Wenn du dann feststellst, die Anforderung an Geschwindigkeit wird nicht erfüllt, dann machst du dir Gedanken noch das letzte Quäntchen an Performance rauszuholen.

Schon am Anfang darüber nachzudenken das Problem über verschachtelte ifs a lá B-Tree zu lösen für einen Zeitgewinn den es evtl. gar nicht bedarf jedoch bei absolut grausamen Code - besser nicht ;)
 

Noctarius

Top Contributor
Als kleiner Vergleich wieso du dir keine Gedanken machen musst:
Wir berechnen pro Sekunde tausende Spielerzonen - ab dieser Zahl musst du dir Gedanken machen. :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Mehrere Werte in einem Switch Case parallel überprüfen Java Basics - Anfänger-Themen 9
D Switch Case Methode aufrufen Java Basics - Anfänger-Themen 3
_so_far_away_ Inventarisierungssystem brauche switch Cases und weiß nicht, wie ich e implementieren muss Java Basics - Anfänger-Themen 5
nelsonmandela Problem bei Ausgabe einer Switch - Case Funktion Java Basics - Anfänger-Themen 5
M error: '.class' expected switch(char) Java Basics - Anfänger-Themen 32
A switch statement Java Basics - Anfänger-Themen 4
volcanos enum und switch (neu): falschen Wert mit IllegalArgumentException oder mit EnumConstantNotPresentException abfangen ? Java Basics - Anfänger-Themen 51
X Enum Abfrage ohne if, for, while oder switch Java Basics - Anfänger-Themen 21
Lion.King switch-Befehl Java Basics - Anfänger-Themen 6
L Switch-Case Multiplikation wird nicht ausgegeben Java Basics - Anfänger-Themen 1
U Warum kann ich die Methode in der ENUM Klasse nicht aufrufen? Und warum geht die Switch nicht? Java Basics - Anfänger-Themen 8
U Warum gibt das eine Nullpointerexception? (Switch) Java Basics - Anfänger-Themen 6
P9cman Vokal Zähler mit switch case und for-Schleife Java Basics - Anfänger-Themen 4
C Potenzberechnung über switch case. Taschenrechner mit Eingabe über einen grafischen Dialog Java Basics - Anfänger-Themen 22
C if-Konstrukt durch switch-Konstrukt ersetzen Java Basics - Anfänger-Themen 14
1 Switch Case Java Basics - Anfänger-Themen 3
T Alternative für switch case Java Basics - Anfänger-Themen 1
C Taschenrechner (switch) in Taschenrechner mit Methoden umwandeln Java Basics - Anfänger-Themen 115
W Taschenrechner mit Switch case Java Basics - Anfänger-Themen 4
B Notensystem Switch-Case Java Basics - Anfänger-Themen 31
S Switch-Case zur Berechnung der Einkommensteuer Java Basics - Anfänger-Themen 15
F Switch case wird als char nicht erkannt.... Java Basics - Anfänger-Themen 6
V Switch Methode macht Code kaputt Java Basics - Anfänger-Themen 18
H Frage zur if-Bedingung bzw switch case Java Basics - Anfänger-Themen 6
S switch case fängt beim letzten case an Java Basics - Anfänger-Themen 6
J Parameterübergabe in switch? Java Basics - Anfänger-Themen 2
M Switch Java Basics - Anfänger-Themen 2
F Switch Case Problem mit Regex lösen? Java Basics - Anfänger-Themen 6
W Wieso funktioniert mein Switch Case nicht ?! Java Basics - Anfänger-Themen 9
F Switch Case Modulo berechnen Java Basics - Anfänger-Themen 12
F Erste Schritte Frage zu simplem Taschenrechner(switch) Java Basics - Anfänger-Themen 16
NoMercy BitFlags Programm (switch on/off , swap und isSet) Java Basics - Anfänger-Themen 7
S Switch-Case für eine Array-Zuordnung Java Basics - Anfänger-Themen 5
S switch und case Java Basics - Anfänger-Themen 1
L Taschenrechner mit switch und while funktioniert noch nicht richtig Java Basics - Anfänger-Themen 22
B Problem bei switch statement Java Basics - Anfänger-Themen 4
D Klassen Problem bei switch-case? Java Basics - Anfänger-Themen 2
E Input/Output Switch ausgabe anpassen bzw. anders darstellen Java Basics - Anfänger-Themen 13
A Warum funktioniert switch aber nicht if/else? Java Basics - Anfänger-Themen 23
B Wiederholen einer if/switch-case Schleife Java Basics - Anfänger-Themen 9
X Nach switch case weiter mit Auswahl Java Basics - Anfänger-Themen 7
T switch case und continue Java Basics - Anfänger-Themen 5
D switch case Code Java Basics - Anfänger-Themen 3
K Erste Schritte switch - Warum sind long/float/double/... nicht erlaubt? Java Basics - Anfänger-Themen 5
Ponychan95 Erste Schritte Switch fällt immer bis zum default durch Java Basics - Anfänger-Themen 4
P Bei Switch-Anweisung wird default-Anweisung angezeigt Java Basics - Anfänger-Themen 4
D kleiner Taschenrechner mit switch fehlerhaft Java Basics - Anfänger-Themen 1
O This in switch anweisung Java Basics - Anfänger-Themen 5
V Fehlerhafte BufferedReader/switch Benutzung? Java Basics - Anfänger-Themen 2
F Erste Schritte Switch case vs. Verschachtelte If Anweisung Java Basics - Anfänger-Themen 11
K Variablen RETURN in Case-Switch / This method must return a result of type Item Java Basics - Anfänger-Themen 4
R Methoden Switch wählt das Falsche Java Basics - Anfänger-Themen 17
B Erste Schritte Addition von double in switch-Anweisung Java Basics - Anfänger-Themen 2
M Endlosschleife bricht durch switch ab Java Basics - Anfänger-Themen 17
R Switch: Nach durchlaufen des Case wieder zum Menü Java Basics - Anfänger-Themen 3
D Array in switch Java Basics - Anfänger-Themen 3
A Switch Case Java Basics - Anfänger-Themen 5
F Reset in der switch Anweisung Java Basics - Anfänger-Themen 3
R Compiler-Fehler Auf selben Array in mehreren "cases" vom "Switch" zugreifen Java Basics - Anfänger-Themen 11
R Switch Werte außerhalb verwenden Java Basics - Anfänger-Themen 2
D Eine Variable in mehreren "switch" Java Basics - Anfänger-Themen 24
M Switch mit String Java Basics - Anfänger-Themen 20
T Erste Schritte switch case Anweisung und if else Verzweigungen? Java Basics - Anfänger-Themen 6
M Variablen Switch Bedingungen Java Basics - Anfänger-Themen 12
A ArrayList-iteration mit Prüfung auf instanceof durch switch case? Java Basics - Anfänger-Themen 13
P Switch Case - Fließkommazahl Java Basics - Anfänger-Themen 2
Z Switch umsetzung Java Basics - Anfänger-Themen 6
lulas[]args Fehlerhafte Switch Java Basics - Anfänger-Themen 6
lulas[]args Switch Schleife - orphaned case Java Basics - Anfänger-Themen 27
W "switch" Anweisung - Rechenzeichen? Java Basics - Anfänger-Themen 5
T kleines problem mit switch case Java Basics - Anfänger-Themen 11
I Methoden Wochenkalendar switch anweisung fehlt Java Basics - Anfänger-Themen 4
C Switch Anweisung Frage Java Basics - Anfänger-Themen 8
R Switch/Case frage: Java Basics - Anfänger-Themen 12
Luk10 Frage zu Switch-Anweisung Java Basics - Anfänger-Themen 11
C Erste Schritte switch Anweisung geht nicht Java Basics - Anfänger-Themen 3
R Switch Abfrage: Found boolean but expected int? Java Basics - Anfänger-Themen 7
T Umschreiben von switch in if else und umgekehrt Java Basics - Anfänger-Themen 9
K Input/Output switch case - Parameterübergabe args[0] Java Basics - Anfänger-Themen 34
P Compilerfehler bei switch-case Java Basics - Anfänger-Themen 18
R 3 Datumsangaben sortieren mittels Switch Java Basics - Anfänger-Themen 9
J Switch mit if anweisung kombinieren Java Basics - Anfänger-Themen 2
D Kann man eine for-Schleife mit switch kombinieren? Java Basics - Anfänger-Themen 8
D Switch und Case Java Basics - Anfänger-Themen 3
F Ps to kW Konvertierer switch-case Problem Java Basics - Anfänger-Themen 4
F Datentypen Ganz simpler Taschenrechner mit switch Java Basics - Anfänger-Themen 10
M '-1' in switch anweisung Java Basics - Anfänger-Themen 2
T Parser mit switch "Weg" ausgeben? Java Basics - Anfänger-Themen 5
Q switch case hier möglich Java Basics - Anfänger-Themen 10
A Switch-Case Problem Java Basics - Anfänger-Themen 17
A Do While mit Switch Case Java Basics - Anfänger-Themen 2
Luk10 switch - Problem Java Basics - Anfänger-Themen 9
S char im switch Java Basics - Anfänger-Themen 16
berti99 Switch-Case || Problem... Java Basics - Anfänger-Themen 6
R Switch-Case Selektion Java Basics - Anfänger-Themen 13
O Switch-Case - Case 4 erhöhen Java Basics - Anfänger-Themen 9
P Problem mit switch-Funktion Java Basics - Anfänger-Themen 5
K Ich verstehe switch einfach nicht Java Basics - Anfänger-Themen 4
M Frage zu Mehrfachauswahl mit switch ... case Java Basics - Anfänger-Themen 3
R Umlaute mit Switch-Case tauschen Java Basics - Anfänger-Themen 26

Ähnliche Java Themen

Neue Themen


Oben