Länge eines stringstreams, wie?


  • Mod

    Dravere schrieb:

    Kannst du die Warnungen hier reinstellen oder mir eine E-Mail mit diesen zuschicken? Ich habe extra alle Warnungen unter MSVC und GCC ausgemerzt 🙂

    Das meiste ist ziemlich harmlos, der Intel Compiler ist bloß traditionell sehr mitteilungsfreudig, besonders wenn man auch noch extra viele Bemerkungen anschaltet. Zeilennummern sind wie in deinem Beitrag+1, weil ich noch ein #include<cstddef> davorschreiben musste für std::size_t. Da die Warnungen bei jeder Instanzierung aufkommen, bringe ich jeweils nur die Warnung für die erste Instanzierung:

    sstream.cc(98): remark #1418: external function definition with no prior declaration
      std::size_t decimal_place_count(T val)
    

    Harmlos.

    sstream.cc(8): warning #63: shift count is too large
        static T const result = ((T)1 << BIT) + max_value_helper<T, BIT - 1>::result;
                                         ^
              detected during:
                instantiation of class "max_value_helper<T, BIT> [with T=unsigned int, BIT=32UL]" at line 27
                instantiation of class "max_value<T> [with T=unsigned int]" at line 51
                instantiation of class "max_decimal_places<T> [with T=unsigned int]" at line 101
                instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Dies allerdings ist interessant.

    sstream.cc(78): remark #981: operands are evaluated in unspecified order
          if((val < 0 && val > -check) || (val >= 0 && val < check))
                             ^
              detected during instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Harmlos. Gleiche Bemerkung für den zweiten Term val<check .

    sstream.cc(78): warning #186: pointless comparison of unsigned integer with zero
          if((val < 0 && val > -check) || (val >= 0 && val < check))
                  ^
              detected during:
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=9UL]" at line 103
                instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Dein Code ist zu flexibel. Wer rechnet schon mit signed Datentypen? 🙂
    Gleiche Warnung für den zweiten Term val >= 0 .

    Diese Warnung wiederholt sich mit jeder Instanzierung, mit immer länger werdender Aufrufliste, bis man dann irgendwann dieses schöne Monstrum bekommt:

    sstream.cc(78): warning #186: pointless comparison of unsigned integer with zero
          if((val < 0 && val > -check) || (val >= 0 && val < check))
                                               ^
              detected during:
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=1UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=2UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=3UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=4UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=5UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=6UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=7UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=8UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=9UL]" at line 103
                instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Zuletzt noch ein "schwerwiegender" Schönheitsfehler:

    sstream.cc(90): remark #869: parameter "val" was never referenced
        static std::size_t count(T val)
                                   ^
              detected during:
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=1UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=2UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=3UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=4UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=5UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=6UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=7UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=8UL]" at line 80
                instantiation of "size_t={unsigned long} decimal_place_counter<T, DECIMAL_PLACES>::count(T) [with T=unsigned int, DECIMAL_PLACES=9UL]" at line 103
                instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Also einfach den unbenutzten Parameternamen entfernen.


  • Administrator

    SeppJ schrieb:

    sstream.cc(8): warning #63: shift count is too large
        static T const result = ((T)1 << BIT) + max_value_helper<T, BIT - 1>::result;
                                         ^
              detected during:
                instantiation of class "max_value_helper<T, BIT> [with T=unsigned int, BIT=32UL]" at line 27
                instantiation of class "max_value<T> [with T=unsigned int]" at line 51
                instantiation of class "max_decimal_places<T> [with T=unsigned int]" at line 101
                instantiation of "size_t={unsigned long} decimal_place_count(T) [with T=unsigned int]" at line 118
    

    Dies allerdings ist interessant.

    Nicht interessant sondern Kopf -> Tisch. Völlig logische Warnung und ganz einfach zu eliminieren:

    template<typename T>
    struct max_value
    {
    private:
      typedef std::numeric_limits<T> limits;
    
      static std::size_t const bits = std::numeric_limits<T>::digits - 1;
    
    public:
      static T const result = max_value_helper<T, bits>::result;
    };
    

    std::numer_limits<T>::digits gibt die Anzahl der nicht Vorzeichenbits zurück. Daher muss ich immer -1 rechnen und nicht nur bei Typen mit Vorzeichenbits.

    Der Rest ist ziemlich klar und einfach abzuschaffen. Einzig vielleicht die Sache mit dem unsigned / signed Problem. Allerdings könnte man da wahrscheinlich etwas mit enable_if oder dergleichen zaubern.

    Danke für die Rückmeldung.

    Grüssli



  • Und warum nicht einfach diese Schleife:

    int n = 1;
    while(x >= 10)
    {
      x /= 10;
      ++n;
    }
    return n;
    

    Dürfte auch nicht (im Schnitt, d.h. gleichverteilt über alle Zahlen) viel langsamer sein, als die if-Kaskade (und ist nicht abhängig von der Datentyp-Größe)...



  • JUDAS! 😃


  • Mod

    Th69 schrieb:

    Und warum nicht einfach diese Schleife:

    int n = 1;
    while(x >= 10)
    {
      x /= 10;
      ++n;
    }
    return n;
    

    Dürfte auch nicht (im Schnitt, d.h. gleichverteilt über alle Zahlen) viel langsamer sein, als die if-Kaskade (und ist nicht abhängig von der Datentyp-Größe)...

    Das ist viel langsamer als alles bisher dagewesene, abgesehen vom Logarithmus. Über 47 Sekunden bei mir für die 0-2^32 Variante und immer noch 21 Sekunden bis 2^16, vergleiche mit knapp 5 s für die if-Kaskade (für beide Varianten). Mal eben ein Faktor 5 bis 10.


  • Administrator

    Ok, hier mal die korrigierte und gekürzte Fassung des Metamonsters 🙂

    #include <limits>
    #include <cstddef>
    
    template<typename T, std::size_t COUNT>
    struct e10
    {
      static T const result = e10<T, COUNT - 1>::result * 10;
    };
    
    template<typename T>
    struct e10<T, 0>
    {
      static T const result = 1;
    };
    
    template<typename T, T CHECK, bool SIGNED = std::numeric_limits<T>::is_signed>
    struct decimal_place_test
    {
    private:
      static T const check = CHECK;
      static T const negative_check = -CHECK;
    
    public:
      static bool test(T val)
      {
        if(val < 0)
        {
          return val > negative_check;
        }
    
        return val < check;
      }
    };
    
    template<typename T, T CHECK>
    struct decimal_place_test<T, CHECK, false>
    {
      static bool test(T val)
      {
        return val < CHECK;
      }
    };
    
    template<typename T, std::size_t PLACES = std::numeric_limits<T>::digits10>
    struct decimal_place_counter
    {
      static std::size_t const decimal_places = PLACES;
      static T const check = e10<T, decimal_places>::result;
    
      static std::size_t count(T val)
      {
        if(decimal_place_test<T, check>::test(val))
        {
          return decimal_place_counter<T, decimal_places - 1>::count(val);
        }
    
        return decimal_places + 1;
      }
    };
    
    template<typename T>
    struct decimal_place_counter<T, 0>
    {
      static std::size_t count(T /*val*/)
      {
        return 1;
      }
    };
    
    /*-------------------------------------------*/
    /* Intel Kompiler Befriedigung               */
    
    template<typename T>
    std::size_t decimal_place_count(T val);
    
    /*                                           */
    /*-------------------------------------------*/
    
    template<typename T>
    std::size_t decimal_place_count(T val)
    {
      return decimal_place_counter<T>::count(val);
    }
    

    @Th69,
    Du vergisst, dass die mehrfache Division deutlich langsamer ist als ein paar Vergleiche und Sprünge.

    Grüssli


  • Mod

    👍
    Erzeugt jetzt nur noch die Bemerkung mit der externen Deklaration und Definition, aber das liegt nur daran, dass ich zu faul bin das Testprogramm in mehrere Dateien aufzuspalten (der guckt nämlich auch danach in welcher Datei die Deklarationen stehen). Zeit für die 0-2^32 Version ist weiterhin gut 5 s, also nur ein kleines bisschen langsamer als die if-Kaskade. 0-2^16 ist ein bisschen weniger effizient.


  • Administrator

    SeppJ schrieb:

    Erzeugt jetzt nur noch die Bemerkung mit der externen Deklaration und Definition, aber das liegt nur daran, dass ich zu faul bin das Testprogramm in mehrere Dateien aufzuspalten (der guckt nämlich auch danach in welcher Datei die Deklarationen stehen).

    Ach blöder Intel Kompiler, kann man ihn nicht einmal austricksen 😃

    Grüssli



  • Also bei mir ist ja die binäre Suche mit Abstand am schnellsten:

    UInt32 get_length(UInt32 x){
        if(x>=100000)//6
            if(x>=100000000)//9
                if(x>=1000000000)//10
                    return 10;
                else
                    return 9;
            else
                if(x>=10000000)//8
                    return 8;
                else
                    if(x>=10000000)//7
                        return 7;
                    else
                        return 6;
        else
            if(x>=1000)//4
                if(x>=10000)//5
                    return 5;
                else
                    return 4;
            else
                if(x>=100)//3
                    return 3;
                else
                    if(x>=10)//2
                        return 2;
                    else
                        return 1;
    }
    


  • Dravere schrieb:

    Übrigens: Wie wäre es noch mit diesem Test:

    struct decimal_place_counter_02
    {
      static UInt32 const max_digits = std::numeric_limits<int>::digits10;
      UInt32 pow10[max_digits];
    
      decimal_place_counter_02()
      {
        UInt32 power = 1;
    
        for(UInt32 i = 0; i < max_digits; ++i)
        {
          power *= 10;
          pow10[i] = power;
        }
      }
    
      UInt32 count(UInt32 x) const
      {
        for(UInt32 i = 0; i < max_digits; ++i)
        {
          if(x < pow10[i])
            return i + 1;
        }
    
        return max_digits + 1;
      }
    };
    
    UInt32 get_length(UInt32 x)
    {
      static decimal_place_counter_02 const counter;
      return counter.count(x);
    }
    

    Geht mir vor allem dabei darum, diese manuelle Aufzählung zu vernichten.

    Process returned 0 (0x0)   execution time : 43.406 s
    27.359
    

    Die schlichte if-Kaskade ist schon sauschnell.
    10 Sekunden @ 2GHz / 2^32 = 4.6 Takte pro Hauptschleifendurchlauf und die Hauptschleife hat eine Abbruchbedingung und hat aufsummiert.



  • life schrieb:

    Also bei mir ist ja die binäre Suche mit Abstand am schnellsten

    Welcher Prozessor?

    @SeppJ: Und bei Dir auf dem I7 die binäre Suche?


  • Mod

    volkard schrieb:

    @SeppJ: Und bei Dir auf dem I7 die binäre Suche?

    Die binäre Suche braucht 7.6 bzw. 6 Sekunden. Immer noch sehr schnell, aber trotzdem gut 30% langsamer als if-Kaskade. Und auch etwas langsamer als das Metamonster.

    Wenn ich mal wild spekulieren darf, würde ich vermuten, dass der i7 bei der if-Kaskade die einzelnen Sprünge recht einfach vorhersagen kann. Bei der binären Suche sind die ifs verschachtelt und die Sprungvorhersage muss mehr arbeiten.



  • volkard schrieb:

    life schrieb:

    Also bei mir ist ja die binäre Suche mit Abstand am schnellsten

    Welcher Prozessor?

    Core2Duo 3GHZ (E8400)

    Hatte allerdings den random-value Test genommen. Bei deinem einfachem raufzähl-Test sind if-Kaskade und binäre Suche etwa gleichwertig bei mir (beides 6 Sekunden).

    Edit: Dafür braucht die neuste Meta-Variante nur etwa 4sec für den raufzähl-Test (VS10) (11364954993 vs 18145459526 ticks).



  • ich wollte eigentlich mal gucken, wieso der unterschied zwischen den ifs(bzw deren reihenfolge) so groß ist, aber bin dabei auf was anderes komisches gestoßen:

    typedef unsigned int UInt32;
    
    #if 0
    //x32 16bit 18.91
    //x32 32bit 28.77
    //x64 16bit 20.80
    //x64 32bit 28.74
    UInt32 get_length(UInt32 x){
        if(x<=9) return 1;
        if(x<=99) return 2;
        if(x<=999) return 3;
        if(x<=9999) return 4;
        if(x<=99999) return 5;
        if(x<=999999) return 6;
        if(x<=9999999) return 7;
        if(x<=99999999) return 8;
        if(x<=999999999) return 9;
        return 10;
    } 
    #elif 1
    //x32 16bit 24.15
    //x32 32bit 6.06
    //x64 16bit 24.07
    //x64 32bit 6.05
    UInt32 get_length(UInt32 x){
        if(x>=1000000000) return 10;
        if(x>=100000000) return 9;
        if(x>=10000000) return 8;
        if(x>=1000000) return 7;
        if(x>=100000) return 6;
        if(x>=10000) return 5;
        if(x>=1000) return 4;
        if(x>=100) return 3;
        if(x>=10) return 2;
        return 1;
    }
    #elif 1
    //x32 16bit 7.21
    //x32 32bit 6.44
    //x64 16bit 8.92
    //x64 32bit 6.56
    UInt32 get_length(UInt32 x){
        if(x>=100000)//6
            if(x>=100000000)//9
                if(x>=1000000000)//10
                    return 10;
                else
                    return 9;
            else
                if(x>=10000000)//8
                    return 8;
                else
                    if(x>=10000000)//7
                        return 7;
                    else
                        return 6;
        else
            if(x>=1000)//4
                if(x>=10000)//5
                    return 5;
                else
                    return 4;
            else
                if(x>=100)//3
                    return 3;
                else
                    if(x>=10)//2
                        return 2;
                    else
                        return 1;
    }
    #endif
    
    #include <iostream>
    
    #include "my/timer.h"
    
    int main()
    {
    	my::timer_t timer;
    
        UInt32 x=0;
        UInt32 s=0;
    
        do {
                s+=get_length(x %65536);
            ++x;
        } while (x != 0);
    
    	my::timer_t::tick_type ticks = timer();
    	std::cout << my::timer_t::get_seconds_from_ticks(ticks) << " seconds" << std::endl;
    
    	std::cout << '\t' << s << std::endl;
    }
    

    hab alle tests mehrfach wiederholt, das ergebnis blieb das gleiche - die extremen schwankungen waren auch im taskmgrU(CPU-Zeit) nachzuvollziehen - also nicht, dass irgend ein prozess iwas blockiert hat...

    msvc9 schrieb:

    /O2 /Oi /GL /D "_MBCS" /FD /EHsc /MD /Gy /Fo"Release\\" /Fd"Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
    

    bzw.

    /O2 /Oi /GL /D "_MBCS" /FD /EHsc /MD /Gy /Fo"x64\Release\\" /Fd"x64\Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
    

    CPU ist auch ein E8400@3,00GHz
    OS Win7, 64bit

    Falls iwer damit mehr anfangen kann als ich:

    do {
                s+=get_length(x %65536);
    000000013FEE1210  movzx       ecx,dx 
    000000013FEE1213  cmp         ecx,9 
    000000013FEE1216  ja          main+2Fh (13FEE121Fh) 
    000000013FEE1218  mov         eax,1 
    000000013FEE121D  jmp         main+0A3h (13FEE1293h) 
    000000013FEE121F  cmp         ecx,63h 
    000000013FEE1222  ja          main+3Bh (13FEE122Bh) 
    000000013FEE1224  mov         eax,2 
    000000013FEE1229  jmp         main+0A3h (13FEE1293h) 
    000000013FEE122B  cmp         ecx,3E7h 
    000000013FEE1231  ja          main+4Ah (13FEE123Ah) 
    000000013FEE1233  mov         eax,3 
    000000013FEE1238  jmp         main+0A3h (13FEE1293h) 
    000000013FEE123A  cmp         ecx,270Fh 
    000000013FEE1240  ja          main+59h (13FEE1249h) 
    000000013FEE1242  mov         eax,4 
    000000013FEE1247  jmp         main+0A3h (13FEE1293h) 
    000000013FEE1249  cmp         ecx,1869Fh 
    000000013FEE124F  ja          main+68h (13FEE1258h) 
    000000013FEE1251  mov         eax,5 
    000000013FEE1256  jmp         main+0A3h (13FEE1293h) 
    000000013FEE1258  cmp         ecx,0F423Fh 
    000000013FEE125E  ja          main+77h (13FEE1267h) 
    000000013FEE1260  mov         eax,6 
    000000013FEE1265  jmp         main+0A3h (13FEE1293h) 
    000000013FEE1267  cmp         ecx,98967Fh 
    000000013FEE126D  ja          main+86h (13FEE1276h) 
    000000013FEE126F  mov         eax,7 
    000000013FEE1274  jmp         main+0A3h (13FEE1293h) 
    000000013FEE1276  cmp         ecx,5F5E0FFh 
    000000013FEE127C  ja          main+95h (13FEE1285h) 
    000000013FEE127E  mov         eax,8 
    000000013FEE1283  jmp         main+0A3h (13FEE1293h) 
    000000013FEE1285  xor         eax,eax 
    000000013FEE1287  cmp         ecx,3B9AC9FFh 
    000000013FEE128D  seta        al   
    000000013FEE1290  add         eax,9 
    000000013FEE1293  add         esi,eax 
            ++x;
    000000013FEE1295  add         edx,1 
        } while (x != 0);
    

    1. variante x64, 16bit zahl

    do {
                s+=get_length(x /*%65536*/);
    000000013FF01210  cmp         ecx,9 
    000000013FF01213  ja          main+2Ch (13FF0121Ch) 
    000000013FF01215  mov         eax,1 
    000000013FF0121A  jmp         main+0A0h (13FF01290h) 
    000000013FF0121C  cmp         ecx,63h 
    000000013FF0121F  ja          main+38h (13FF01228h) 
    000000013FF01221  mov         eax,2 
    000000013FF01226  jmp         main+0A0h (13FF01290h) 
    000000013FF01228  cmp         ecx,3E7h 
    000000013FF0122E  ja          main+47h (13FF01237h) 
    000000013FF01230  mov         eax,3 
    000000013FF01235  jmp         main+0A0h (13FF01290h) 
    000000013FF01237  cmp         ecx,270Fh 
    000000013FF0123D  ja          main+56h (13FF01246h) 
    000000013FF0123F  mov         eax,4 
    000000013FF01244  jmp         main+0A0h (13FF01290h) 
    000000013FF01246  cmp         ecx,1869Fh 
    000000013FF0124C  ja          main+65h (13FF01255h) 
    000000013FF0124E  mov         eax,5 
    000000013FF01253  jmp         main+0A0h (13FF01290h) 
    000000013FF01255  cmp         ecx,0F423Fh 
    000000013FF0125B  ja          main+74h (13FF01264h) 
    000000013FF0125D  mov         eax,6 
    000000013FF01262  jmp         main+0A0h (13FF01290h) 
    000000013FF01264  cmp         ecx,98967Fh 
    000000013FF0126A  ja          main+83h (13FF01273h) 
    000000013FF0126C  mov         eax,7 
    000000013FF01271  jmp         main+0A0h (13FF01290h) 
    000000013FF01273  cmp         ecx,5F5E0FFh 
    000000013FF01279  ja          main+92h (13FF01282h) 
    000000013FF0127B  mov         eax,8 
    000000013FF01280  jmp         main+0A0h (13FF01290h) 
    000000013FF01282  xor         eax,eax 
    000000013FF01284  cmp         ecx,3B9AC9FFh 
    000000013FF0128A  seta        al   
    000000013FF0128D  add         eax,9 
    000000013FF01290  add         esi,eax 
            ++x;
    000000013FF01292  add         ecx,1 
        } while (x != 0);
    

    1. Variante, x64, 32bit Zahl

    do {
                s+=get_length(x /*%65536*/);
    000000013F261210  cmp         ecx,3B9ACA00h 
    000000013F261216  jb          main+2Fh (13F26121Fh) 
    000000013F261218  mov         eax,0Ah 
    000000013F26121D  jmp         main+9Dh (13F26128Dh) 
    000000013F26121F  cmp         ecx,5F5E100h 
    000000013F261225  jb          main+3Eh (13F26122Eh) 
    000000013F261227  mov         eax,9 
    000000013F26122C  jmp         main+9Dh (13F26128Dh) 
    000000013F26122E  cmp         ecx,989680h 
    000000013F261234  jb          main+4Dh (13F26123Dh) 
    000000013F261236  mov         eax,8 
    000000013F26123B  jmp         main+9Dh (13F26128Dh) 
    000000013F26123D  cmp         ecx,0F4240h 
    000000013F261243  jb          main+5Ch (13F26124Ch) 
    000000013F261245  mov         eax,7 
    000000013F26124A  jmp         main+9Dh (13F26128Dh) 
    000000013F26124C  cmp         ecx,186A0h 
    000000013F261252  jb          main+6Bh (13F26125Bh) 
    000000013F261254  mov         eax,6 
    000000013F261259  jmp         main+9Dh (13F26128Dh) 
    000000013F26125B  cmp         ecx,2710h 
    000000013F261261  jb          main+7Ah (13F26126Ah) 
    000000013F261263  mov         eax,5 
    000000013F261268  jmp         main+9Dh (13F26128Dh) 
    000000013F26126A  cmp         ecx,3E8h 
    000000013F261270  jb          main+89h (13F261279h) 
    000000013F261272  mov         eax,4 
    000000013F261277  jmp         main+9Dh (13F26128Dh) 
    000000013F261279  cmp         ecx,64h 
    000000013F26127C  jb          main+95h (13F261285h) 
    000000013F26127E  mov         eax,3 
    000000013F261283  jmp         main+9Dh (13F26128Dh) 
    000000013F261285  cmp         ecx,0Ah 
    000000013F261288  sbb         eax,eax 
    000000013F26128A  add         eax,2 
    000000013F26128D  add         esi,eax 
            ++x;
    000000013F26128F  add         ecx,1 
        } while (x != 0);
    

    2. Variante, x64, 32bit Zahl

    do {
                s+=get_length(x %65536);
    000000013FC61210  movzx       eax,cx 
    000000013FC61213  cmp         eax,3B9ACA00h 
    000000013FC61218  jb          main+31h (13FC61221h) 
    000000013FC6121A  mov         eax,0Ah 
    000000013FC6121F  jmp         main+99h (13FC61289h) 
    000000013FC61221  cmp         eax,5F5E100h 
    000000013FC61226  jb          main+3Fh (13FC6122Fh) 
    000000013FC61228  mov         eax,9 
    000000013FC6122D  jmp         main+99h (13FC61289h) 
    000000013FC6122F  cmp         eax,989680h 
    000000013FC61234  jb          main+4Dh (13FC6123Dh) 
    000000013FC61236  mov         eax,8 
    000000013FC6123B  jmp         main+99h (13FC61289h) 
    000000013FC6123D  cmp         eax,0F4240h 
    000000013FC61242  jb          main+5Bh (13FC6124Bh) 
    000000013FC61244  mov         eax,7 
    000000013FC61249  jmp         main+99h (13FC61289h) 
    000000013FC6124B  cmp         eax,186A0h 
    000000013FC61250  jb          main+69h (13FC61259h) 
    000000013FC61252  mov         eax,6 
    000000013FC61257  jmp         main+99h (13FC61289h) 
    000000013FC61259  cmp         eax,2710h 
    000000013FC6125E  jb          main+77h (13FC61267h) 
    000000013FC61260  mov         eax,5 
    000000013FC61265  jmp         main+99h (13FC61289h) 
    000000013FC61267  cmp         eax,3E8h 
    000000013FC6126C  jb          main+85h (13FC61275h) 
    000000013FC6126E  mov         eax,4 
    000000013FC61273  jmp         main+99h (13FC61289h) 
    000000013FC61275  cmp         eax,64h 
    000000013FC61278  jb          main+91h (13FC61281h) 
    000000013FC6127A  mov         eax,3 
    000000013FC6127F  jmp         main+99h (13FC61289h) 
    000000013FC61281  cmp         eax,0Ah 
    000000013FC61284  sbb         eax,eax 
    000000013FC61286  add         eax,2 
    000000013FC61289  add         esi,eax 
            ++x;
    000000013FC6128B  add         ecx,1 
        } while (x != 0);
    

    2. Variante, x64, 16bit Zahl

    do {
                s+=get_length(x %65536);
    000000013F801210  movzx       ecx,dx 
    000000013F801213  cmp         ecx,186A0h 
    000000013F801219  jb          main+51h (13F801241h) 
    000000013F80121B  cmp         ecx,5F5E100h 
    000000013F801221  jb          main+40h (13F801230h) 
    000000013F801223  cmp         ecx,3B9ACA00h 
    000000013F801229  sbb         eax,eax 
    000000013F80122B  add         eax,0Ah 
    000000013F80122E  jmp         main+7Ah (13F80126Ah) 
    000000013F801230  mov         eax,6 
    000000013F801235  cmp         ecx,989680h 
    000000013F80123B  cmovae      eax,r8d 
    000000013F80123F  jmp         main+7Ah (13F80126Ah) 
    000000013F801241  cmp         ecx,3E8h 
    000000013F801247  jb          main+66h (13F801256h) 
    000000013F801249  cmp         ecx,2710h 
    000000013F80124F  sbb         eax,eax 
    000000013F801251  add         eax,5 
    000000013F801254  jmp         main+7Ah (13F80126Ah) 
    000000013F801256  cmp         ecx,64h 
    000000013F801259  jb          main+72h (13F801262h) 
    000000013F80125B  mov         eax,3 
    000000013F801260  jmp         main+7Ah (13F80126Ah) 
    000000013F801262  cmp         ecx,0Ah 
    000000013F801265  sbb         eax,eax 
    000000013F801267  add         eax,2 
    000000013F80126A  add         esi,eax 
            ++x;
    000000013F80126C  add         edx,1 
        } while (x != 0);
    

    3. variante x64, 16bit zahl

    Kann mir das irgendwer erklären? -.-

    bb



  • Tja, die gemeinen Compiler.



  • Th69 schrieb:

    Im Vergleich zum restlichen Programm (z.B. bei Benutzereingaben) spielt daher die Performance wohl nur eine untergeordnete Rolle.
    Meines Erachtens hier also ganz klar ein Fall von "POITROAE" (Premature optimization is the root of all evil)!

    Ach, hier gehts doch schon lange nicht mehr um reale Programme, sondern um Sport 🙂



  • Hä, wo ist denn jetzt mein Beitrag hin?
    Schön, daß du - Michael - wenigstens meinen letzten Satz zitiert hast...



  • Th69 schrieb:

    Hä, wo ist denn jetzt mein Beitrag hin?

    Weg. Weil Du überhaupt nicht verstanden hast, was der zitierte Satz bedeutet, und in anderen Forum wie RundUmDieProgrammierung bitte nachfragst.



  • volkard, willst du mich jetzt veräppeln?

    Ich habe eine klare Antwort auf die Frage von "unskilled" gegeben, nämlich daß die Testdaten für die unterschiedliche Performance bzgl. der if-Kaskaden zuständig sind.
    Hier nocheinmal in Zahlen (bei 0 bis 2^32):
    1-stellig: 9 (bzw. 10 wenn man die Null dazuzählt)
    2-stellig: 90
    3-stellig: 900
    ...
    8-stellig: 90000000
    9-stellig: ~3.3 Mrd.

    Also nocheinmal: über 90% der Zahlen sind 8 bzw. 9-stellig!!!



  • So ein Posting hätte ich auch erfreut stehen lassen.


Anmelden zum Antworten