need for speed



  • Schoenen guten Tag zusammen,
    ich wurde gerne mein Programm etwas schneller machen. Der Profiler sagt, ich verbrate viel Zeit bei folgenden Actionen:
    ...
    prefix=id/10000;
    ...
    suffix=id%10000;

    Was ich hier mache ist, eine maximal 8-stellige Zahl (id) in die ersten 4 Ziffern
    (prefix) und die letzten 4 Ziffern (suffix) zu zerlegen. prefix, suffix und id sind int.
    Da diese Programmstelle sehr oft ausgefuehrt wird, verbrauche ich hier 13% der Zeit. Gibt es eine Moeglickeit, das zu beschleunigen?



  • zerlegst du bei jedem Durchlauf eine andere ID? Oder arbeitest du immer mit dem selben Wert? Im letzten Fall wäre es vielleicht angebracht, "prefix" und "suffix" nur einmal zu berechnen und danach zu merken.

    (PS: Eventuell liegen auch in der Umgebung dieser Anweisungen noch Optimierungsmöglichkeiten - zeig doch mal etwas mehr Code)



  • In jedem Durchlauf wird eine andere ID zerlegt werden. Ich dachte daran, ob es vielleicht auf Bit-Ebene eine Moeglichkeit gibt, die beiden Rechenschritte schneller auszufuehren?
    Im Rest der Funktion liegt kein weiters Potential, denke ich.

    int PF_Get_Index(PDT_INDEX *ip,int id){
    int prefix,suffix;

    if(ip<=0){
    return -1;
    }

    prefix=id/10000;
    if(prefix >= ip->maxpre){
    return -1;
    }
    if( ((ip->prep)+prefix)->suffixp == 0 ){
    return -1;
    }

    suffix=id%10000;
    if(suffix >= ((ip->prep)+prefix)->maxsuffix ){
    return -1;
    }
    return *((((ip->prep)+prefix)->suffixp)+suffix);

    }



  • Guck dir mal die Funktion div aus stdlib.h und ihre Verwandten an, die rechnet dir den Quotienten und den Rest gleichzeitig aus. Wenn das nicht reicht, dann poste nochmal.



  • Also bei einer Zerlegung bezüglich einer Zehnerpotenz dürfte Bit-Arbeit etwas -hmm- schwierig werden. Du könntest höchstens deine Datenstruktur so umordnen, daß du die ID hexadezimal aufspaltest:

    prefix=id>>16;
    suffix=id&0xFFFF;
    

    PS: Vielleicht kannst du dein Programm auch etwas umstrukturieren, so daß du diese Funktion nicht ganz so häufig aufrufen mußt.



  • Also die Verwendung der div Funktion hat die Sache sogar langsamer gemacht. Statt 11.4s laeuft das Programm jetzt 15.0s.
    Wie man die Haeufigkeit der Aufrufe verringern kann, seh ich im Moment noch nicht. Das Programm liest Nastran Karten ein und bevor es diese speichert, muss es nachschauen, ob die Id der Nastran Karte schon existiert. Dazu wird die ID in prefix und suffix zerlegt.
    Das sagt uebrigens der Profiler:

    % cumulative self self total
    time seconds seconds calls s/call s/call name
    13.51 1.73 1.73 17631860 0.00 0.00 PF_Get_Index
    8.82 2.86 1.13 1 1.13 4.98 PF_Read_Nastran_Bulk_Data
    5.78 3.60 0.74 4444778 0.00 0.00 PF_AsToIn
    4.53 4.18 0.58 1278555 0.00 0.00 PF_Format_Bulk_File_Line
    3.28 4.60 0.42 2 0.21 0.45 PF_Print_Missing_Items_Grid
    3.04 4.99 0.39 2213629 0.00 0.00 PF_AsToFl
    ...
    ...



  • skoll1 schrieb:

    Also die Verwendung der div Funktion hat die Sache sogar langsamer gemacht. Statt 11.4s laeuft das Programm jetzt 15.0s.
    Wie man die Haeufigkeit der Aufrufe verringern kann, seh ich im Moment noch nicht. Das Programm liest Nastran Karten ein und bevor es diese speichert, muss es nachschauen, ob die Id der Nastran Karte schon existiert. Dazu wird die ID in prefix und suffix zerlegt.

    Wieviele Karten verarbeitest du da im Schnitt? Vielleicht wäre es ja günstiger, ein Array mit den Zuordnungen ID -> Index zu speichern und dort nachzuschauen, ob deine Karte schon vorhanden ist. (wenn du immer darauf achtest, daß dieses Array sortiert ist, sollte das auch recht schnell gehen)



  • Genau das mache ich, aber eine ID kann eine 8 stellige Zahl sein und ein so grosses Feld wollte ich nicht anfordern. Deshalb hab ich so eine Art zweidimensionales Feld entwickelt das man mit prefix und suffix anspricht und das nur an den Stellen waechst, an denen es noetig ist.
    Ich verarbeite 2 Millionen Karten und mehr.
    Hab jetzt mal versucht, die Funktion als inline zu definieren indem ich vor die Definition und Deklaration ein inline geschrieben habe. Compiliert mit -O. Aber ohne Erfolg. Bringt 0.1s. Arbeite unter HPUX mit gcc 3.4.3.



  • Hast du es mal mit meinem obigen Code versucht (mit den Bit-Operatoren)?



  • Also ich hab einfach mal
    prefix=id/10000;
    durch
    prefix=id>>16;
    ersetzt und entsprechendes auch mit suffix gemacht. Dann kommt aber was anderes fuer prefix und suffix raus. Hab ich falsch gemacht oder?



  • Ich sagte doch - das zerteilt die ID hexadezimal ;). (d.h. du mußt die selbe Anpassung überall machen, wo du mit deinem Index-Array umgehst)


Anmelden zum Antworten