Was ist schneller? If oder Switch/Case
-
Hi,
weiß jemand welchen Schleife schneller bearbeitet wird?
Sowas: if (d[3] & 0x80) ...
if (d[3] & 0x81) ...Oder: Switch(d[3]{
case 0x80: ...
case 0x81: ...Ich benutze diese Schleifen sehr oft in meinem Programm um den Zustand der Variablen abzufragen. Meist gibt es nur 2-3 Möglichkeiten (0x80,0x81,0x82), aber das ganze ist sehr zeitkritisch, es kommt auf jeden µs an.
-
wenn dann würde ich schon mit else if arbeiten...
generell kann man das IMHO nicht sagen. schau dir mal den asm code an, dann wirst du sehen was in deinem fall schneller ist...
-
Ja nach Compiler.
Wird ein char untersucht oder ein int?
Können die 3 werte garantiert werden, also kein default?
Liegt ne Schieflage in der Verteilung der Werte vor?
(Tendenz geht eher zu switch.)
-
Kanns sein das das switch-Konstrukt einfach eine höhere Abstraktionsebene für das else-if-Konstrukt darstellt?
Wenn dem so wäre, ist else-if schneller ...
-
Die Schlussfolgerung, dass mehr Abstraktion gleichbedeutend mit geringerer Geschwindigkeit ist, ist nicht logisch nachvollziehbar.
-
Original erstellt von Delirium:
Kanns sein das das switch-Konstrukt einfach eine höhere Abstraktionsebene für das else-if-Konstrukt darstellt?
Wenn dem so wäre, ist else-if schneller ...Beweise!
Abstraktion kostet keine performance!
-
Original erstellt von Delirium:
Kanns sein das das switch-Konstrukt einfach eine höhere Abstraktionsebene für das else-if-Konstrukt darstellt?
Wenn dem so wäre, ist else-if schneller ...switch ist doch dazu da, daß der compiler sprungtabellen anlegen kann, oder warum wohl hat man die vergleiche auf vergleiche auf gleichheit mit integralen konstanten festgelegt? na, klar, weil's indizes für ne sprungtabelle sind. das ist performance pur. nur stellt sich die frage, ob das bei nur drei werten schon gut ankommt. nicht vergessen darf man die beiden vergleiche, ob die zahlen im erlaubten sprungtabellenbereich sind. ein vergleich reicht wenn man vorher um nen gescheiten index zu kriegen den kleinsten wert subtrahiert und wenn mann dann unsigned gegen (größen-kleinsten) vergleicht...
aber abschalten kann man diesen vergleich bei manchen compilern sogar. deshalb fragte ich, ob man sicher sein kann, daß nur drei werte seinm können.
also in diese richtung haben die überlegungen zu gehen. und immer brav auf shade hören, wenn er sagt, daß abstraktion keine performance kostet.
-
Kanns sein das das switch-Konstrukt einfach eine höhere Abstraktionsebene für das else-if-Konstrukt darstellt?
Wenn dem so wäre, ist else-if schneller ...Genau. Und void main ist Standard und fflush(stdin) leert den Eingabepuffer.
Für alle die es nicht bemerkt haben sollten: Das war Ironie.
-
*duckduck*
War ja nur so in den Raum gestelltund immer brav auf shade hören, wenn er sagt, daß abstraktion keine performance kostet.
Möchte aber trotzdem noch mal gerne nachhaken:
Ist das praktisch gesehen nicht falsch? Dann müssten C++ Programme doch genauso schnell wie Asm Pendants laufen !? Tun sie aber nicht, weil die höherere Abstraktionsebene von C++ Code nicht wieder optimal in Asm-Code deabstrahiert werden kann(aufgrund der Unfähigkeit der Compiler Programmierer).Rede ich da nur Blödsinn vor mich her?
[ Dieser Beitrag wurde am 24.05.2002 um 16:06 Uhr von Delirium editiert. ]
-
Original erstellt von dukelc4:
**Hi,
weiß jemand welchen Schleife schneller bearbeitet wird?
Sowas: if (d[3] & 0x80) ...
if (d[3] & 0x81) ...Oder: Switch(d[3]{
case 0x80: ...
case 0x81: ...Ich benutze diese Schleifen sehr oft in meinem Programm um den Zustand der Variablen abzufragen. Meist gibt es nur 2-3 Möglichkeiten (0x80,0x81,0x82), aber das ganze ist sehr zeitkritisch, es kommt auf jeden µs an.**
Hmmm... irgendwie frag ich mich dabei, ob die beiden Arten überhaupt äquivalent sind? Bei deinen IFs wird ein Bit-Operator verwendet, bei dem switch ist ja sowieso immer nur ein Vergleich... versteh ich nicht ganz...
lg, phreaking
-
@Volkard
Es geht um ein unsigned char Array in dem ich eine Nachricht, die am Parallelport empfangen wird, speichere. Je nachdem was im 3. Arrayfeld für einen Id steht soll die Nachricht weiterverarbeitet werden. Als nächstes wird dann das 4. Feld abgefragt und entsprechend dem empfangenen Wert eine Funktion ausgeführt.[ Dieser Beitrag wurde am 24.05.2002 um 21:53 Uhr von dukelc4 editiert. ]
-
@phreaking
Öehm klar, es muss dann wohl so heißen:Sowas: if (d[3] && 0x80) ...
if (d[3] && 0x81) ...Oder: Switch(d[3]{
case 0x80: ...
case 0x81: ...
-
also, alle if - versionen mit & sind nicht aquivalent zu dem switch:
if (d[3] && 0x80) ... if (d[3] && 0x81) ...
is das gleiche wie
if (d[3]) ... if (d[3]) ...
Und
if (d[3] & 0x80) ... if (d[3] & 0x81) ...
Hat nix mit
Switch(d[3]{ case 0x80: ... case 0x81: ...
zu tun.
Warum immer so kompliziert. Warum nicht direkt:
if (d[3] == 0x80) ... if (d[3] == 0x81) ...
[ Dieser Beitrag wurde am 24.05.2002 um 23:42 Uhr von virtual editiert. ]
-
Original erstellt von Delirium:
Ist das praktisch gesehen nicht falsch? Dann müssten C++ Programme doch genauso schnell wie Asm Pendants laufen !? Tun sie aber nicht, weil die höherere Abstraktionsebene von C++ Code nicht wieder optimal in Asm-Code deabstrahiert werden kann(aufgrund der Unfähigkeit der Compiler Programmierer).berechtigte Frage.
asm ist verdammt schnell. Aber abstraktion hat damit nichts zu tun.
2 mal 'mov' und einmal 'int' ist natuerlich schneller als printf()
aber: printf macht ja auch mehr als nur 2 movs und 1 int! printf parst den ganzen stringdas ist nur ein einfaches Beispiel, aber es zeigt, dass wenn mehr funktionalitaet willst, es mit performance bezahlst.
versuch in asm einmal ein schnelleres strlen() als dass der C Library hinzubekommen. gleichschnell kannst du schaffen wenn du gut asm kannst, schneller wohl kaum.
-
if (d[3] & 0x80) ... if (d[3] & 0x81) ...
macht nur dann sin wenn es darum geht auf gewisse Bits zu testen.
0x80 ist binär 10000000 testet also wird getestet, ob das achte Bit gesetzt ist. 0x81 testet auf das achte und erste und 82 auf das achte und zweite.
Die switchversion macht einen direkten vergleich. Das ist was ganz anderes
Beispiel der wert ist 0x82 und wird mit 0x80 undverknüpft. Dann bleibt bit acht stehen, wodurch die Bedingung als Wahr gilt.
switch oder auch == testen auf gleicheit, wodurch 0x82 und 0x80 nicht das selbe sind.Die Frage ist also: Was ist gewünscht?
und Teste doch einfach die Laufzeitgeschwindigkeit selbst:
in time.h gibts ne funktion namens clock()
-
asm ist verdammt schnell.
LOL. Ein sprache kann wohl kaum schnell sein. Es kommt nur darauf an, wie du es Programmierst. In ASM kann man schnelle Programme erstellen.
Und mit der Abstraktion ist das so eine Sache. Es kommt immer darauf an, wie gut sich diese Abstraktion auflösen lässt.
-
Original erstellt von Shade Of Mine:
berechtigte Frage.
2 mal 'mov' und einmal 'int' ist natuerlich schneller als printf()
aber: printf macht ja auch mehr als nur 2 movs und 1 int! printf parst den ganzen stringman könnte sich einen compiler vorstellen der nach den jeweiligen anforderungen verscheidene formen einer funktion bereithält die auf die jeweilige aufgabe optimiert ist...
aber das wäre krank zu implementieren.p.s. ich bin eher für 2 mal 'mov' und einmal 'stosb'
-
printf() ist eine externe Funktion und in C kann man Funtkionen nicht überladen.
-
Original erstellt von Shade Of Mine:
versuch in asm einmal ein schnelleres strlen() als dass der C Library hinzubekommen. gleichschnell kannst du schaffen wenn du gut asm kannst, schneller wohl kaum.Sicher kriegste das schneller! Ein ASM-Block im Code ist auf jeden Fall schneller als ein Funktionsaufruf von strlen(), bei dem die Prefetch-Queue gelöscht wird (spitzfindig, ich weiß ). Außerdem wird ja noch der Stackrahmen erstellt, kostet auch 'n paar Takte...
[ Dieser Beitrag wurde am 28.05.2002 um 23:42 Uhr von Cocaine editiert. ]
-
Original erstellt von Helium:
printf() ist eine externe Funktion und in C kann man Funtkionen nicht überladen.aber es ist dem compiler überlassen wie er die standardlib implementiert... d.h. er kann aus diesen aufrufen machen was er will solange sie ihre aufgabe erfüllen...