Gibt es hier Performance Unterschiede?
-
Da ich kein Fan von aneinandergeketteten Abfragen bin schreibe ich lieber
A
if (board.black_queens >= 1) { if (black_king_attacker_n >= 2) { if (material_item->black_non_pawn_material >= VALUE_QUEEN_O) { if (black_king_adjacent_zone_attack_n) { // ...anstatt
B
if (board.black_queens >= 1 && black_king_attacker_n >= 2 && material_item->black_non_pawn_material >= VALUE_QUEEN_O && black_king_adjacent_zone_attack_n && // ...Ist das dasselbe für den Compiler, oder gibt es Performance-Unterschiede? Ich kann das nur schwierig testen, da meine gesamten Sources wie in A angelegt sind.
Und was ist eurer Meinung nach besser ?
Danke schonmal für eure Statements

-
Es ist nicht dasselbe für den compiler, moderne compiler machen aber daraus den selben code.
Solche verschachtelten Bedingungsblöcke sind Unsinn. Setze anstatt dessen einfach die boolschen Operatoren an eine konstante Tab-Stelle, damit die Bedingunsliste übersichtlicher aussieht.
-
Solche verschachtelten Bedingungsblöcke sind prima.
-
Ich würde sagen B kann nicht schlechter sein als A. Beim "&&", auch "short circuit AND" genannt, wird der zweite Operand nur auswertet, wenn der erste Operand
trueist. Aber A könnte langsamer sein als B. Nicht vielleicht in Deinem Fall, aber wenn man zB Intervalle testet:int foo(int x) { if (1 <= x && x <= 3) return 23; return 42; } int bar(int x) { if (1 <= x) if (x <= 3) return 23; return 42; }Im ersten Fall könnte ein schlauer Compiler den Test 1<=x&&x<=3 zu etwas wie unsigned(i-1)<=2 umbauen (eine Verzweigung gespart). Im zweiten Fall halte ich das nicht mehr so ganz für wahrscheinlich, dass ein Compiler diese Optimierung auch durchfuhren kann.
Wenn Du's genau wissen willst, kannst Du Dir ja mal den generierten Assemblercode anschauen.
Edit: Hier ist der Assembler code (g++ version 3.4.5 auf x86 mit -O3)
00000000 <__Z3fooi>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 08 mov 0x8(%ebp),%eax 6: 5d pop %ebp 7: 48 dec %eax 8: 83 f8 03 cmp $0x3,%eax b: 19 c0 sbb %eax,%eax d: 83 e0 ed and $0xffffffed,%eax 10: 83 c0 2a add $0x2a,%eax 13: c3 ret 14: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 1a: 8d bf 00 00 00 00 lea 0x0(%edi),%edi 00000020 <__Z3bari>: 20: 55 push %ebp 21: 89 e5 mov %esp,%ebp 23: 8b 55 08 mov 0x8(%ebp),%edx 26: 85 d2 test %edx,%edx 28: 7e 0a jle 34 <__Z3bari+0x14> 2a: 83 fa 03 cmp $0x3,%edx 2d: b8 17 00 00 00 mov $0x17,%eax 32: 7e 05 jle 39 <__Z3bari+0x19> 34: b8 2a 00 00 00 mov $0x2a,%eax 39: 5d pop %ebp 3a: c3 ret 3b: 90 nopDas erste sieht mir irgendwie effizienter aus, da keine bedingten Sprünge.
Gruß,
SP
-
volkard schrieb:
Solche verschachtelten Bedingungsblöcke sind prima.
Finde ich nicht:
if (board.black_queens >= 1) { if (black_king_attacker_n >= 2) { if (material_item->black_non_pawn_material >= VALUE_QUEEN_O) { if (black_king_adjacent_zone_attack_n) { ... Anweisungen } } } }if( board.black_queens >= 1 && black_king_attacker_n >= 2 && material_item->black_non_pawn_material >= VALUE_QUEEN_O && black_king_adjacent_zone_attack_n ) { ... Anweisungen }
-
Ja, ich habs wiedermal komplett verpeilt. Wenn der Code komplizierter wird, ist auf jeden Fall Deine Version viel lesbarer, weil man den Ausdruck nicht inhaltlich zerlegen muß, sondern das einfach grafisch machen kann. Durch die Eingerückten &&-Zeichen ist sofort die totale Übersicht da.
bool datumIstGueltig(int tag,int monat,int jahr) { if( monat>0 && monat<13 && tag>0 && tag<32 && (tag<31 ¦¦ (monat>7!=monat%2==1)) && (monat!=2 ¦¦ (tag<30 && (((jahr%4==0 && jahr%100!=0) ¦¦ jahr%400==0) ¦¦ tag<29)))) return true; else return false; }edit: Übersicht drastisch weiter verbessert, indem || auch einen Platz bekommen hat. Evtl sollte man für Vergleichsoperatoren auch einen Platz einräumen.
-
(A) ist auch angenehmer zu debuggen.
ich verwende trotzdem meist (B).
-
Ich finde B auch besser, weil es imo mehr das aussagt, was du sagen willst. Du willst, dass etwas UND etwas UND etwas nochmal anderes gleichezeitig wahr sind. Klar versteht man es mit if's auch, aber mit den Verknüpfungen finde ich es intuitiver.
-
drakon schrieb:
Ich finde B auch besser, weil es imo mehr das aussagt, was du sagen willst. Du willst, dass etwas UND etwas UND etwas nochmal anderes gleichezeitig wahr sind. Klar versteht man es mit if's auch, aber mit den Verknüpfungen finde ich es intuitiver.
wieso sagt ihr das alle so absolut?
ich finds idR auch schöner, logische operatoren statt 100 ifs zu benutzen, aber volkards bsp find ich z.bsp. mehr als unleserlich - aber das würd ich eh anders schreiben:bool datumIstGueltig(int tag,int monat,int jahr) { /*0...32, 0...11, 0...INT_MAX*/ if(tag < 0) return false; switch(monat) { case 0: //jan case 2: //mrz case 4: //mai case 6: //jul case 7: //aug case 9: //oct case 11: //dez return tag < 32; case 3: //apr case 5: //jun case 8: //sep case 10: //nov return tag < 31; case 1: //feb if((jahr%4 == 0) && (jahr%400 == 0)) return tag < 29; return < 28; default: return false; } }bb
-
unskilled schrieb:
wieso sagt ihr das alle so absolut?
Was war bei meiner Aussage absolut? - Ich habe gesagt, dass ich es (dort, ok habe ich nicht explizit gesagt..) intuitiver finde. Klar gibt es Fälle, wo es anderst rum besser verständlich ist.
Und auf volkards Beispiel habe ich mich gar nicht bezogen. - Deine Lösung gefällt mir da auch besser.
