PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C/C++: was ist schneller - "<" oder "<="



lou_ziffer
17-10-2003, 10:56
Hallo Forum -
mich "quält" schon des längeren eine Frage bezüglich Codeoptimierung bei for-Schleifen in C/C++.

Wenn ich z.B. 2 simple for-Schleife habe wie:

for (i=0; i<10; ++i)
und
for (i=1; i<=10; ++i)

Ist dann die 2. der beiden langsamer als die 1 (wegen "<=" anstatt "<")?
Benötigt Vergleich kleiner-gleich also 2 Operationen - in etwa wie (i < 10) || (i == 10)?

Und angenommen ich habe folgendes:

for (i=0; I<=max; ++i)

Wäre es dann eine optimierung, wäre also dann das Programm schneller wenn ich vorher max um 1 verringere um dann in der for-Schleife "kleiner" verwenden kann? Also so etwa:

max -= 1;
for (i=0; I<max; ++i)

-------
Und noch eine andere kleine Unklarheit: Macht es abgesehen davon, daß der Wert der Zuweisung ein anderer ist, einen Unterschied, von der Performance her, ob man zum inkrementieren einer Variable i++ oder ++i schreibt?

Kennt vielleicht jemand ein Buch zum Thema Codeoptimierung in C/C++, bzw. existieren überhaupt Bücher zu diesem Thema?

xare
17-10-2003, 11:05
Teste es doch ganz einfach. :) Warum so viel Theorie?

MfG Xare

anda_skoa
17-10-2003, 11:17
Original geschrieben von lou_ziffer
Benötigt Vergleich kleiner-gleich also 2 Operationen - in etwa wie (i < 10) || (i == 10)?

Das dürfte von den Möglichkeiten des Prozessors abhängen.
Allerdings kenn ich keinen, dem die <= Operation fehlen würde, bzw. der dafür mehr Zyklen brauchen würde, als für einen < Vergleich.



Und noch eine andere kleine Unklarheit: Macht es abgesehen davon, daß der Wert der Zuweisung ein anderer ist, einen Unterschied, von der Performance her, ob man zum inkrementieren einer Variable i++ oder ++i schreibt?

Wenn der Rückgabewert der Expression nicht benutzt wird, sollte eigentlich jeder Compiler den selben Code dafür generieren, d.h. es wird ziemlich sicher kein Unterschied sein.

Ciao,
_

axeljaeger
17-10-2003, 11:21
die erste ist mit an sicherheit grenzender Wahrschienlichkeit schneller, besonders wenn einer auf ie Idee kommt, einen Float als Zählervariable zu nehmen.

Lin728
17-10-2003, 12:04
Hi there!

Ich weiß das ist off-topic, aber eventuell denkst du ja an Optimierung im gewöhnlichen Sinn, sprich normalen Code im Prozentbereich zu beschleunigen:

An derartigen Sachen zu feilen, macht ehrlich gesagt wenig Sinn.
Ob man sich einen Prozessorzyklus spart oder nicht macht selbst bei millionenfachem durchlauf fast keinen Sinn.

Hier eine kleine Tabelle was am meisten hilft:

1.) Algorythmusoptimierung
2.) Zeitaufwändige Api-Aufrufe vermeiden. (= z.B. new, malloc, x-funktionen, blabla).
3.) Profilier verwenden.


lg

kehj
17-10-2003, 12:10
Mein C-Dozent hat mal die 10 Grundregeln des Optimierens erläutert:

1. Optimieren Sie nie!
2. Optimieren Sie nie!
3. Optimieren Sie nie!
[...]
10. Besorgen Sie sich einen Profiler und gucken sie, welches die langsamen Routinen sind...

Ist was dran. Persönlich würde ich auch nur unter Zuhilfenahme eines CVS optimieren.
Ich hab mir dabei schon so oft das Programm zuschossen. Und natürlich immer 1-2 Tage vor Abgabe...

kehj

peschmae
17-10-2003, 14:13
Hat durchaus was an sich :)

allerdings kann man sich auch n CVS durcheinanderbringen :D
vor allem wenn mans nur als billige Backup-funktion benötigt und nicht beherrscht. Ich spreche aus erfahrung :(

MfG Peschmä

JoelH
17-10-2003, 22:41
Original geschrieben von axeljaeger
die erste ist mit an sicherheit grenzender Wahrschienlichkeit schneller, besonders wenn einer auf ie Idee kommt, einen Float als Zählervariable zu nehmen.

Wer da Floats benutzt gehört gesteinigt ;) Wie auch immer, ein cleverer Compiler macht aus einem <= 20 einfach ein <21 und dadurch hat er alles wieder raus.

viel interessanter ist da der Müll ob ich mit i++ oder ++i erhöhe, siehe dazu =>
http://www.c-plusplus.de/forum/viewtopic.php?t=34084&highlight=

amiga
17-10-2003, 23:39
< und <= macht keinen unterschied.

was wohl etwas ausmacht, ist das auflösen von abzählbaren for()-schleifen....

also aus

for(i=0;i<10;i++) printf("Hallo %d\n",i);

... sowas machen :

printf("Hallo %d\n",0);
printf("Hallo %d\n",1);
printf("Hallo %d\n",2);
printf("Hallo %d\n",3);
printf("Hallo %d\n",4);
printf("Hallo %d\n",5);
printf("Hallo %d\n",6);
printf("Hallo %d\n",7);
printf("Hallo %d\n",8);
printf("Hallo %d\n",9);

ist etwas schneller ;) *g* sieht auch toll aus wenn man das bei programmen macht die schleifen von 0-20000 haben *g* deshalb gibts beim gcc die optimierungs-option "-funroll-loops", die das automatisch beim kompilieren erledigt, aber halt nur für kleinere schleifen .... sonst macht es keinen sinn ;)

comrad
20-10-2003, 12:07
Hi

ich gehe einfach mal davon aus, dass < schneller ist als <=, sofern der Prozessor nicht einen Befehl dafür bereit hält, der dieses schon in einem Schritt erledigt (unterhalb der Schrittbasis brauchen wir uns um Verzögerungen keine Gedanken machen, weil diese so minimal sind, dass man es niemals merken würde).

a < b
ist a kleiner b - wäre das kommando im prozessor

a <= b
(ist a kleiner b) ODER (ist a gleich b) - das wären zwei kommandos im prozessor.


deswegen meine vermutung, dass <= langsamer ist. allerdings, wenn du dir um sowas schon gedanken machen musst, dann wär dir wirklich assembler anzuraten ;)

comrad

christophwth
24-10-2003, 02:30
Hi

schaut euch mal die unterschiede an wenn das ganze z.B als einfache zähleschleife ohne schleifenrupf ausgeführt wird. [z.B, so for ( ; ; ); ]


.file "schneller1.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl $0, -4(%ebp)
.L2:
cmpl $9, -4(%ebp)
jle .L4
jmp .L3
.L4:
leal -4(%ebp), %eax
incl (%ea
x)
jmp .L2
.L3:
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 3.3.2 (Debian)"




.file "schneller2.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl $1, -4(%ebp)
.L2:
cmpl $10, -4(%ebp)
jle .L4
jmp .L3
.L4:
leal -4(%ebp), %eax
incl (%eax)
jmp .L2
.L3:
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 3.3.2 (Debian)"

ich seh da keinen wesentlichen unterschied

gruss
christoph

JoelH
24-10-2003, 11:58
Original geschrieben von christophwth
.......


.......
.L2:
cmpl $9, -4(%ebp)
..........



...........
.L2:
cmpl $10, -4(%ebp)
.................

ich seh da keinen wesentlichen unterschied

gruss
christoph

Der macht genau dass was ich mir gedacht und gepostet hab :)


Original geschrieben von JoelH
Wie auch immer, ein cleverer Compiler macht aus einem <= 20 einfach ein <21 und dadurch hat er alles wieder raus.