if/else - Ausführungsgeschwindigkeit



  • Mr. N schrieb:

    Das zweite ist natürlich schneller, weil er sonst das return zweimal ausführt.

    hä? 😕

    @speedii: es wird so keinen Unterschied machen, der Übersetze Code ist mit ziemlich großer Wahrscheinlichkeit gleich.

    /* test.c */
    typedef int BOOL;
    
    int test1(BOOL var) {
      if(var) {
        return !var;
      }
      return var;
    }
    
    int test2(BOOL var) {
      if(var) {
        return !var;
      }
      else {
        return var;
      }
    }
    

    Ohne Code Optimierung:

    supertux@supertux:~> gcc test.c -c -g
    supertux@supertux:~> objdump -d test.o 
    
    test.o:     file format elf32-i386
    
    Disassembly of section .text:
    
    00000000 <test1>:
       0:   55                      push   %ebp
       1:   89 e5                   mov    %esp,%ebp
       3:   83 ec 04                sub    $0x4,%esp
       6:   83 7d 08 00             cmpl   $0x0,0x8(%ebp)
       a:   74 0f                   je     1b <test1+0x1b>
       c:   83 7d 08 00             cmpl   $0x0,0x8(%ebp)
      10:   0f 94 c0                sete   %al
      13:   0f b6 c0                movzbl %al,%eax
      16:   89 45 fc                mov    %eax,-0x4(%ebp)
      19:   eb 06                   jmp    21 <test1+0x21>
      1b:   8b 45 08                mov    0x8(%ebp),%eax
      1e:   89 45 fc                mov    %eax,-0x4(%ebp)
      21:   8b 45 fc                mov    -0x4(%ebp),%eax
      24:   c9                      leave  
      25:   c3                      ret    
    
    00000026 <test2>:
      26:   55                      push   %ebp
      27:   89 e5                   mov    %esp,%ebp
      29:   83 ec 04                sub    $0x4,%esp
      2c:   83 7d 08 00             cmpl   $0x0,0x8(%ebp)
      30:   74 0f                   je     41 <test2+0x1b>
      32:   83 7d 08 00             cmpl   $0x0,0x8(%ebp)
      36:   0f 94 c0                sete   %al
      39:   0f b6 c0                movzbl %al,%eax
      3c:   89 45 fc                mov    %eax,-0x4(%ebp)
      3f:   eb 06                   jmp    47 <test2+0x21>
      41:   8b 45 08                mov    0x8(%ebp),%eax
      44:   89 45 fc                mov    %eax,-0x4(%ebp)
      47:   8b 45 fc                mov    -0x4(%ebp),%eax
      4a:   c9                      leave  
      4b:   c3                      ret
    

    wie du siehst sind beide Funktionen gleich (bis auf Zeile 19h und 3fh wegen des jmp Befehls)

    Mit Optimierung:

    supertux@supertux:~> gcc test.c -c -g -O2
    supertux@supertux:~> objdump -d test.o 
    
    test.o:     file format elf32-i386
    
    Disassembly of section .text:
    
    00000000 <test1>:
       0:   55                      push   %ebp
       1:   31 c0                   xor    %eax,%eax
       3:   89 e5                   mov    %esp,%ebp
       5:   5d                      pop    %ebp
       6:   c3                      ret    
       7:   89 f6                   mov    %esi,%esi
       9:   8d bc 27 00 00 00 00    lea    0x0(%edi),%edi
    
    00000010 <test2>:
      10:   55                      push   %ebp
      11:   31 c0                   xor    %eax,%eax
      13:   89 e5                   mov    %esp,%ebp
      15:   5d                      pop    %ebp
      16:   c3                      ret
    

    sind beide Aufrufe bis auf die letzten Zeilen gleich, also hast du einen Geschwindigkeitsgewinn von wenigen Zyklen, also kaum messbar, würde ich sagen.



  • supertux schrieb:

    00000000 <test1>:
       0:   55                      push   %ebp
       1:   31 c0                   xor    %eax,%eax
       3:   89 e5                   mov    %esp,%ebp
       5:   5d                      pop    %ebp
       6:   c3                      ret    
       7:   89 f6                   mov    %esi,%esi
       9:   8d bc 27 00 00 00 00    lea    0x0(%edi),%edi
    
    00000010 <test2>:
      10:   55                      push   %ebp
      11:   31 c0                   xor    %eax,%eax
      13:   89 e5                   mov    %esp,%ebp
      15:   5d                      pop    %ebp
      16:   c3                      ret
    

    die letzten beiden zeilen von <test1> werden nie ausgeführt. ausserdem geben beide codes immer 0 im eax register zurück. was war'n das für'n schäbiger compiler?
    🙂



  • disasm-freak schrieb:

    die letzten beiden zeilen von <test1> werden nie ausgeführt.

    Sollen ja auch nicht. Mittelschlechte Kompiler hätten diesen Bereich einfach "vollgeNOPpt".
    Dadurch wird dann immer das Listing unnötig "lang" (finde ich).



  • padding schrieb:

    disasm-freak schrieb:

    die letzten beiden zeilen von <test1> werden nie ausgeführt.

    Sollen ja auch nicht.

    ach so, und warum wird die funktion auf 16 bytes vergrössert? wegen der CPU caches? die andere funktion hat auch bloss 7 bytes.
    🙂



  • _Z1fb:
    .LFB2:
            xorl    %eax, %eax
            ret
    

    Sagt der Super-Noob.



  • @Mr. N: Copy-Paste von Compilerausgaben sind als Beweis des nicht-n00b-seins nicht geeignet :D.

    Und ein gescheiter Compiler/Linker macht den Code eh Inline (spart vor allem die Kopiererei der Register beim Aufruf und macht den Code kleiner und somit ein bisschen schneller :))



  • Superlexx schrieb:

    @Mr. N: Copy-Paste von Compilerausgaben sind als Beweis des nicht-n00b-seins nicht geeignet :D.

    Ich habe nicht vor, zu beweisen, dass ich kein Noob bin.



  • Ah, sorry, habe

    Mr. N schrieb:

    Sagt der Super-Noob.

    als Ironie misverstanden. Kommt nicht wieder vor 😉



  • War das keine Ironie? o_O

    Ähh.. achja, was soll ich denn benutzen..
    Was ist stilistisch schöner/besser? 🙂



  • speedii schrieb:

    Was ist stilistisch schöner/besser?

    ohne else.
    🙂


Anmelden zum Antworten