Optimieren, need help



  • ------------- schrieb:

    drum das 1D Array weil der GrafikSpeicher nunmal ein 1D Array ist! Drum liegt alles als 1D Array vor.

    Das ist hier ja jedem klar 🙄

    Denn es gibt keine BITMAP Struktur

    void CBitmap::drawNormal (...
    


  • *lol*, schon gut, nur nicht aufregen !!! 😃



  • ch habe assert neu definiert und assert erwartet nun einen bool!

    Dann schreib doch

    assert(m_buffer != 0)
    

    Was heißt denn jetzt dein C dann?



  • ------------ schrieb:

    ...

    das C hat nichts mit MFC zu tun sondern bedeutet in meinem Programm Conquer, weil die bibliothek so heißt.

    ...

    Ok das mit dem Assert stimmt das != 0 auch gehen würde, sonstige optimierungsvorschläge?



  • 1.die funktion in mehrere blöcke aufteilen, damit das nicht so ein riesen wurstteil ist,dann optimiert sich das schon wie von selbst

    2. lass das C ganz weg und mach

    namespace Conquer{
    }
    

    präfixe und ungarische notation ist tot

    und nochwas: wenn dua ssert neu definierst oder andre änderungen machst, dann musst du uns das mitteilen, wir können nix optimieren, was wir nicht kennen.

    //edit
    3. wieso willste das optimieren, hast du da geschwindigkeitseinbußen entdeckt?



  • Optimizer schrieb:

    ch habe assert neu definiert und assert erwartet nun einen bool!

    Dann schreib doch

    assert(m_buffer != 0)
    

    Das ist gar nicht mal noetig. Ein einfaches

    assert(m_buffer);
    

    reicht voellig aus, da der Zeiger automatisch in eine boolischen Wert konvertiert
    wird.

    mfg
    v R



  • neben den ganzen hässlich- und merkwürdigkeiten, die dein Programmierstil beinhält, ist das Hauptproblem für die Ineffizient die Verwendung von Schleifen und von byte (bzw. 2byte) weise Kopier vorgängen. Verwende memcpy oder so was, wenn es geht, da diese Funktion deutlich effizienter sein sollte, als jeder Schleife.

    Das wars, was ich auf den ersten Blick gesehen habe



  • virtuell Realisticer schrieb:

    Das ist gar nicht mal noetig. Ein einfaches

    assert(m_buffer);
    

    reicht voellig aus, da der Zeiger automatisch in eine boolischen Wert konvertiert
    wird.

    Jo, dachte ich eigentlich auch, das war auch mein erster Vorschlag. Irgendwie hat -------- dann gemeint, er hat es redefiniert und es frisst jetzt ein bool 😮 aha!?). Naja ich wollte des gar nicht so genau wissen, wieso und wie das assert redefiniert ist 🙄 .



  • Au weia, au weia, au weia. Ohne dir zu nahe treten zu wollen, aber der Code ist wirklich dreckig. Zur Performance komm ich nachher noch, aber erst mal Programmierstil allgemein - kapsel deinen verdammten Code. Du hast allein in dieser kleinen Funktion zig Stellen, an denen du den selben Code immer und immer wieder stehen hast. Du könntest die Code-Größe deutlich verringen (und auch ein bisschen speed rausholen), wenn du zum Beispiel erst auf clipping und danach auf transparente Pixel prüfst, denn so wie der Code im Moment aussieht, ist es dir, wenn clipping an ist, eh egal, ob du transparente Pixel hast. Jedenfalls ist der Code haargenau gleich. Und wenn ich das richtig sehe, ist der Code für nicht clipping und keine transparenten Pixel eigentlich auch genau der gleiche, nur dass du m_height und m_width fest gecodet hast, obwohl in diesem Fall srcBottom, srcTop usw. genau die entsprechenden Werte haben.

    Dann hast du einige völlig unnötige Zuweisungen - srcLeft und srcTop sind schon 0, das musst du ihnen nicht mehr zuweisen. Eigentlich kannst du srcRight und srcBottom auch gleich entsprechend initialisieren.

    Ansonsten - memcpy benutzen.

    Ohne das jetzt groß getestet zu haben (Ich hab im Moment keinen Compiler zur Hand, und den Rest deines Codes kenn ich ja auch nicht...), ich denke, das hier sollte das selbe tun wie deine Methode, und wenn nicht, sollte zumindest die Idee klar werden, so dass du was damit anfangen kannst.

    void CBitmap::drawNormal (int x, int y, unsigned short *dest)
    {
        assert (m_buffer);
    
        unsigned short *source = m_hasTransparentPixels ? m_rleBuffer : (m_buffer + srcLeft + srcTop * m_width);
    
        int srcLeft   = x < 0 ? -x : 0;
        int srcTop    = y < 0 ? -y : 0;
    
        dest += x + srcLeft + (y + srcTop) * g_screenWidth;
    
        if (m_hasTransparentPixels)
        {
            int realCount = 0;
            int index     = 0;
    
            for(int i = 0; i < m_height;) {
                if (!source [index]) {
                    ++index;
                    dest      += source[index];
                    realCount += source[index];
                    ++index;
                } else {
                    memcpy(dest, &source[index + 1], source[index] * sizeof(unsigned short));
    
                    realCount += source[index];
                    dest      += source[index];
                    index     += source[index] + 1;
                }
    
                if(realCount == m_width) {
                    realCount = 0;
                    dest += g_screenWidth - m_width;
                    ++i;
                }
            }
        } else {
            int srcRight  = x + m_width  > g_screenWidth  ? g_screenWidth  - x : m_width ;
            int srcBottom = y + m_height > g_screenHeight ? g_screenHeight - y : m_height;
    
            for (int i=srcTop; i<srcBottom; ++i) {
                memcpy(dest, src, (srcRight - srcLeft) * sizeof(unsigned short));
    
                source += m_width;
                dest   += g_screenWidth;
            }
        }
    }
    


  • Whoopsie, kleiner Fehler unterlaufen. also so:

    void CBitmap::drawNormal (int x, int y, unsigned short *dest)
    {
        assert (m_buffer);
    
        unsigned short *source = m_hasTransparentPixels ? m_rleBuffer : (m_buffer + srcLeft + srcTop * m_width);
    
        int srcLeft   = x < 0 ? -x : 0;
        int srcTop    = y < 0 ? -y : 0;
        int srcRight  = x + m_width  > g_screenWidth  ? g_screenWidth  - x : m_width ;
        int srcBottom = y + m_height > g_screenHeight ? g_screenHeight - y : m_height;
    
        int no_clipping = srcLeft | srcTop | srcRight | srcBottom;
    
        dest += x + srcLeft + (y + srcTop) * g_screenWidth;
    
        if (m_hasTransparentPixels && no_clipping)
        {
            int realCount = 0;
            int index     = 0;
    
            for(int i = 0; i < m_height;) {
                if (!source [index]) {
                    ++index;
                    dest      += source[index];
                    realCount += source[index];
                    ++index;
                } else {
                    memcpy(dest, &source[index + 1], source[index] * sizeof(unsigned short));
    
                    realCount += source[index];
                    dest      += source[index];
                    index     += source[index] + 1;
                }
    
                if(realCount == m_width) {
                    realCount = 0;
                    dest += g_screenWidth - m_width;
                    ++i;
                }
            }
        } else {
            for (int i=srcTop; i<srcBottom; ++i) {
                memcpy(dest, src, (srcRight - srcLeft) * sizeof(unsigned short));
    
                source += m_width;
                dest   += g_screenWidth;
            }
        }
    }
    


  • Wieso ich keinen namespace benutze und assert neu definiere und kein memcpy benutzen kann ist einfach: ich kann keine Standardlib benutzen? Wie denn auch wenn ich sie für meine Zwecke nicht mitlinken darf?

    @0xdeadbeef
    danke.

    @otze
    nur weil ich m_ und g_ benutze heißt das das ich die ganze Ungarische Notation benutze? Nö. nur 2 sachen die sich für mich persönlich durchgesetzt haben! Merk dir: es gibt nicht immer nur schwarz und weis sondern auch graustufen.



  • achja zum assert:
    CBitmap.cpp(244) : warning C4800: 'unsigned short *' : forcing value to bool 'true' or 'false' (performance warning)



  • ------------ schrieb:

    achja zum assert:
    CBitmap.cpp(244) : warning C4800: 'unsigned short *' : forcing value to bool 'true' or 'false' (performance warning)

    ja, die warnung stört. ich hab mir für den msvc ein eigenes idiom ausgedacht, was nur diese warnung auszumachen hat.

    assert(!!m_buffer);
    

    bei m_buffer?true:false muss ich erst genau lesen, was passert. das !! ist als ein symbol erkennbar. und assert(bool(m_buffer)) macht die warnung nicht aus.



  • Man könnte natürlich auch die Zeiger einfach auf 0 testen... dürfte den selben Code generieren wie assert(pointer), IMHO. Bedeutet also das selbe und ist auch noch klarer, wie ich finde.



  • Optimizer schrieb:

    Man könnte natürlich auch die Zeiger einfach auf 0 testen... dürfte den selben Code generieren wie assert(pointer), IMHO. Bedeutet also das selbe und ist auch noch klarer, wie ich finde.

    nee.
    ich frage mit assert(pdata), ob der zeiger gültig ist. mit assert(pdata!=0) frage ich bloß, ob er gleich 0 ist (und nach sekundenlanger überlegung komme ich bestimmt drauf, daß das aussagt, ob er gültig ist). das ist für mich ein großer unterschied, auch wenn hume gleich andeuten wird, daß ich immer aus ner mücke nen elefanten mache.



  • Ich bin von Java verdorben und bevorzuge daher, explizit den Vergleich mit 0 hinzuschreiben. Naja auch net wild, solang mans lesen kann...
    Mach nicht immer aus ner Mücke nen Elefanten. 😉 🤡

    Willkommen Newbie

    Auf diese Seite zu kommen ist wahrscheinlich die erste kluge Entscheidung von dir. Hier lernst
    du alles was du brauchst um dir selbstständig Information mit Google zu besorgen. In diesem
    Tutorial wird beschrieben, wie du einen C++ Kurs mit Google finden kannst.

    Ich krieg mich nicht mehr. 😃



  • ------------- schrieb:

    Wieso ich keinen namespace benutze und assert neu definiere und kein memcpy benutzen kann ist einfach: ich kann keine Standardlib benutzen? Wie denn auch wenn ich sie für meine Zwecke nicht mitlinken darf?

    also ich musste noch nie etwas mitlinken, um namespaces benutzen zu können...hmmm liegts vielleicht daran, dass "namespace" ein normales c++ schlüsselwort wie "int" oder "class" ist? :p

    und wieso zum geier willst du die stl nicht benutzen? die ist doch eigentlich das, was c++ ausmacht

    @otze
    nur weil ich m_ und g_ benutze heißt das das ich die ganze Ungarische Notation benutze? Nö. nur 2 sachen die sich für mich persönlich durchgesetzt haben! Merk dir: es gibt nicht immer nur schwarz und weis sondern auch graustufen.

    und alle diese graustufen sind absolut häßlich 🙄. schon allein die unterstriche sind ne sünde und urhäßlich, aber sie dann auch noch als präfix trenner zu mißbrauchen....tzz 👎



  • otze schrieb:

    und wieso zum geier willst du die stl nicht benutzen? die ist doch eigentlich das, was c++ ausmacht

    falsch.

    und assert muß man umdefinieren, weil das alte assert keine destruktoren aufruft.



  • hmm gehört die stl nicht mehr zum standard?
    und beschreibt der standard nicht mehr, was für inhalte die sprache haben muss?



  • Die STL gehört zum Standard, aber was die Sprache ausmacht, sind eher ihre Paradigmen - im Fall von C++ vor allem das generische und das objektorientierte Paradigma.


Anmelden zum Antworten