Performance Krimskrams



  • Hallo, folgender Threat artet hoffentlich nicht in einen Flamewar aus, denn es wird um micro optimizing gehen 😃
    Wenn ich die Funktion memcpy aufrufe, welche Variante sollte ich bevorzugen, um die beste Performance zu erhalten?

    size_t index=100;
    int *p = new int [index];
    int *q = new int [index];
    
    memcpy(p, q, sizeof(int[index])); //Variante a
    memcpy(p, q, sizeof(int)*index); //Variante b
    
    const unsigned short var = sizeof(int);
    memcpy(p, q, var*index); //variante c
    

    Bei Variante b würde ja die Multiplikation "Zeit rauben". Allerdings weis ich nicht, wie die Anzahl bytes bei Variante a ermittelt wird. Ist da etwas im Standard vorgeschrieben?
    Zu Variante c: Stellt sizeof(typ) eine Art Funktionsaufruf da? Oder wandelt das der Compiler beim Kompilieren in einen konstanten Wert um? Wenn Ersteres zutriff, würde es ja Sinn machen, denn Wert von sizeof(typ) in einer const Variablen zu speichern. Oder ist die zweite Variante durch den Standard vorgeschrieben? Wenn nein, wie kann ich sehen, wie mein kompiler sizeof() behandelt?


  • Administrator

    1. sizeof wird zur Kompilezeit ausgewertet. Sehr praktisch in der Templatemetaprogrammierung, da es als eine Art Ersatz für typeof dienen kann 🙂
      2. Soweit ich weiss, würde Variant a 4 ergeben. Nämlich 4 Bytes für einen int auf einem 32 Bit System 😉
      3. Ich würde Variante b vorziehen, Variante c ist eigentlich genau das gleiche, nur eine unnötige zusätzliche Kurve, welche aber sehr wahrscheinlich wegoptimiert würde.

    Grüssli



  • Dravere schrieb:

    2. Soweit ich weiss, würde Variant a 4 ergeben. Nämlich 4 Bytes für einen int auf einem 32 Bit System

    Nein

    size_t index=100;
    cout<<sizeof(int)*index;  //Ausgabe: 400
    cout<<sizeof(int[index]); //Ausgabe: 400
    

  • Administrator

    Oh, sorry, hab mich da verlesen. Dachte dort steht q[index] . Allerdings geht die Variante sowieso nicht wirklich:

    #include <iostream>
    
    int main()
    {
    	int i;
    	std::cin >> i;
    
    	std::cout << sizeof(int[i]) << std::endl;
    
    	return 0;
    }
    

    Führt zu einem Kompilerfehler, weil i nicht konstant ist. Ist dein index erst zur Laufzeit bekannt? Was wohl sehr wahrscheinlich der Fall sein wird, dann geht die Variante a sowieso nicht 🙂

    Grüssli



  • Ja, habe ich auch gerade erst gemerkt.
    Code::Blocks sagt nichts, aber VisualStudio 2008 Express heult rum 😃 trotzdem Danke 🙂



  • @Zeitkritisch:
    Die meisten Compiler werden wohl den selben Code erzeugen, egal was du verwendest. D.h. solange es so ein einfaches Beispiel wie bei dir ist, und der Compiler sicher sein kann, dass index zwischen der =100 Zuweisung, und dem memcpy nicht modifiziert wird.

    Generell ist das aber "blunzn", weil der Unterschied wohl nicht merkbar sein wird.

    Wenn du wirklich 100.1% sicher gehen willst, dann schreib doch einfach sizeof(int) * 100 .

    Wenn der Wert für index allerdings irgendwie dynamisch ermittelt wird, dann ist es erst wieder egal, da der Compiler sowieso eine Multiplikation (bzw. Shift-Instruction) generieren muss. Ganz egal mit welcher Syntax du es schreibst.

    p.S.: da Shiften *sehr* schnell geht, ist es sogar "ober-blunzn^2", also vergiss es einfach, und schreib es so, wie's am besten lesbar ist!


Anmelden zum Antworten