vector oder multimap?



  • Hi,
    Ich habe ein Problem und zwar kann ich mich nicht entscheiden ob ich <vector> oder doch <multimap> verwenden sollte.. Ich habe ein CPoint Klasse gschrieben die einzelne Punkte speichert und diese später im Konsolenfenster ausgibt (ist eine Art Zeichenklasse)...Nun die Punkte haben auch ID's die der Benutzer der Klasse selbst setzen kann, nun weiß ich nicht wie ich es machen soll, ich hab mal eine Version von CPoint mit benutzung eines <vector>'s geschrieben

    *.h :

    #ifndef CPOINT_H
    #define CPOINT_H
    
    #include "..\apptypedefs.h"
    #include "nssrdraw.h"        // <- Wichtige Header für alle SRDraw-Klassen
    
    #include <vector>
    
    // CPoint dient zum speichern einzelner Punkte und zeichnet diese im Konsolenfenster.
    // In Fehlersuche ist sie ziemlich beschränkt und kontrolliert nur das nötigste und stellt
    // diese Werte richtig, aber Fehlerausgaben wird man nie zu sehen bekommen
    
    class CPoint
    {
        private :
            struct POINT_DATA
            {
                BYTE       _nvChar;  // Numerischer Wert eines Zeichens
                srd::COLOR _clr;     // Farbe des Punktes
                USHORT     _x;       // X/Y-Position
                USHORT     _y;       // des Punktes
                UINT       _ID;      // ID des Punktes
            };
    
            typedef std::vector<POINT_DATA>           VPD;
            typedef std::vector<POINT_DATA>::iterator VPD_IT;
    
        public:
            // KONSTRUKTORE
    
            // size, Anfangsgröße des Containers
            // add, Vergrößerung des Containers falls er voll ist
            // Reserviert Speicherplatz & initialisiert _size & _add
            CPoint(size_t size, size_t add) : _size(size), _add(add)
            {
                _vpd.reserve(size);
            }
    
            // Leert den Inhalt des Containers
            ~CPoint()
            {
                _vpd.clear();
            }
    
            CPoint(const CPoint &rCpy);
    
            // DE/INITIALISIERUNGSMETHODEN
            void InitNewPoint(BYTE nvChar, UINT id, srd::COLOR clr, USHORT xPos, USHORT yPos);  // Speichert einen neuen Punkt
    
            void Remove(UINT pos);  // Ein Punkt wird gelöscht
            void Remove(UINT beg, UINT end);  // Alle Punkte im Bereich beg-1 - end werden gelöscht
            void Remove(UINT pointID, UINT beg, UINT end);  // Alle Punkte im Bereich beg-1 - end die die als Parameter übergebene pointID haben,
                                                            // werden gelöscht
    
            // ZEICHENMETHODEN
            void Draw();  // Zeichnet alle Punkte
            void Draw(UINT pos);  // Zeichnet den Punkt der auf pos-1 gespeichert ist
            void Draw(UINT beg, UINT end);  // Zeichnet alle Punkte im Bereich beg-1 - end-1
            void Draw(UINT pointID, UINT beg, UINT end);  // Zeichnet alle Punkte im Bereich beg-1 - end-1 die die als Parameter übergebene pointID haben
    
            // OPERATOR ÜBERLADUNG
            CPoint& operator=(const CPoint &rp);
            CPoint& operator+(const CPoint &rp);
            CPoint& operator+=(const CPoint &rp);
    
            // INFO
            size_t get_size() const { return _vpd.size(); }  // Gibt die Anzahl an Punkte zurück
    
        private:
            // KONTROLLMETHODEN
            void checkXY(USHORT &x, USHORT &y) const;
            void compare(UINT &val1, UINT &val2) const;
    
            // EIGENSCHAFTEN
            VPD    _vpd;  // Container, %vector
            size_t _size; // Aktuelle Größe(Kapazität) von _vpd
            size_t _add;  // Vergrößerung des Containers FALLS er voll ist
    };
    
    #endif // CPOINT_H
    

    *.cpp

    #include <iostream>
    #include "cpoint.h"
    
    //
    // KONSTRUKTORE
    //
    
    CPoint::CPoint(const CPoint &rCpy) : _size(rCpy.get_size()), _add(rCpy._add)
    {
        _vpd.reserve(_size);
        copy(rCpy._vpd.begin(), rCpy._vpd.end(), back_inserter(_vpd));
    }
    
    //
    // DE/INITIALISIERUNGSMETHODEN
    //
    
    void CPoint::InitNewPoint(BYTE nvChar, UINT id, srd::COLOR clr, USHORT xPos, USHORT yPos)
    {
        POINT_DATA tmp;
    
        checkXY(xPos, yPos);  // Falls "falsche" Werte übergeben wurden, werden sie richtig gestellt
    
        tmp._nvChar = nvChar;
        tmp._ID     = id;
        tmp._clr    = clr;
        tmp._x      = xPos;
        tmp._y      = yPos;
    
        if(get_size() == _size)  // Ist der Container voll?
        {
            _size += _add;
            _vpd.reserve(_size);  // Speicherplatz für weitere _add Punkte reservieren
        }
    
        _vpd.push_back(tmp);
    }
    
    void CPoint::Remove(UINT pos)
    {
        VPD_IT itPos = _vpd.begin();
    
        advance(itPos, pos-1);
        _vpd.erase(itPos);
    }
    
    void CPoint::Remove(UINT beg, UINT end)
    {
        VPD_IT itBeg = _vpd.begin(),
               itEnd = itBeg;
    
        advance(itBeg, beg-1);
        advance(itEnd, end);
    
        _vpd.erase(itBeg, itEnd);
    }
    
    void CPoint::Remove(UINT pointID, UINT beg, UINT end)
    {
        VPD_IT itBeg = _vpd.begin(),
               itEnd = itBeg;
    
        advance(itBeg, beg-1);
        advance(itEnd, end);
    
        for( ; itBeg < itEnd; ++itBeg)
        {
            if(itBeg->_ID == pointID)
            {
                _vpd.erase(itBeg);
                --itBeg;
                --itEnd;
            }
        }
    }
    
    //
    // ZEICHENMETHODEN
    //
    
    void CPoint::Draw()
    {
        VPD_IT it = _vpd.begin();
    
        for( ; it < _vpd.end(); ++it)
        {
            srd::SetTxtClr(it->_clr);
            srd::MoveTo(it->_x, it->_y);
    
            std::cout << it->_nvChar;
        }
    }
    
    void CPoint::Draw(UINT pos)
    {
        VPD_IT it = _vpd.begin();
        advance(it, pos-1);
    
        srd::SetTxtClr(it->_clr);
        srd::MoveTo(it->_x, it->_y);
    
        std::cout << it->_nvChar;
    }
    
    void CPoint::Draw(UINT beg, UINT end)
    {
        VPD_IT itBeg = _vpd.begin(),
               itEnd = itBeg;
    
        advance(itBeg, beg-1);
        advance(itEnd, end);
    
        for( ; itBeg < itEnd; ++itBeg)
        {
            srd::SetTxtClr(itBeg->_clr);
            srd::MoveTo(itBeg->_x, itBeg->_y);
    
            std::cout << itBeg->_nvChar;
        }
    }
    
    void CPoint::Draw(UINT pointID, UINT beg, UINT end)
    {
        VPD_IT itBeg = _vpd.begin(),
               itEnd = itBeg;
    
        advance(itBeg, beg-1);
        advance(itEnd, end);
    
        for( ; itBeg < itEnd; ++itBeg)
        {
            if(itBeg->_ID == pointID)
            {
                srd::SetTxtClr(itBeg->_clr);
                srd::MoveTo(itBeg->_x, itBeg->_y);
    
                std::cout << itBeg->_nvChar;
            }
        }
    }
    
    //
    // OPERATOR ÜBERLADUNG
    //
    
    CPoint& CPoint::operator=(const CPoint &rp)
    {
        if(this == &rp)
            return *this;
    
        _vpd.clear();
    
        if(_vpd.capacity() < rp.get_size())  // Nicht genug Platz?
        {
            size_t n = rp.get_size() - _vpd.capacity();  // Für wieviele Elemente zusätzlichen Speicher anfordern?
            _size += n;
            _vpd.reserve(_size);
        }
    
        copy(rp._vpd.begin(), rp._vpd.end(), back_inserter(_vpd));
    
        return *this;
    }
    
    CPoint& CPoint::operator+(const CPoint &rp)
    {
        if(rp.get_size() < 1)
            return *this;
    
        size_t free = _size - get_size();  // Freier Speicherplatz ermitteln
    
        if(free < rp.get_size())  // Muss man Speicherplatz reservieren?
        {
            _size += (rp.get_size() - free);
            _vpd.reserve(_size);  // Nur reservieren was man auch braucht
        }
    
        copy(rp._vpd.begin(), rp._vpd.end(), back_inserter(_vpd));
    
        return *this;
    }
    
    CPoint& CPoint::operator+=(const CPoint &rp)
    {
        if(rp._vpd.size() < 1)
            return *this;
    
        size_t free = _size - _vpd.size();  // Freier Speicherplatz ermitteln
    
        if(free < rp.get_size())  // Muss man Speicherplatz reservieren?
        {
            _size += (rp.get_size() - free);
            _vpd.reserve(_size);  // Nur reservieren was man auch braucht
        }
    
        copy(rp._vpd.begin(), rp._vpd.end(), back_inserter(_vpd));
    
        return *this;
    }
    
    //
    // KONTROLLMETHODEN
    //
    
    void CPoint::checkXY(USHORT &x, USHORT &y) const
    {
        if(x < 1)
        {
            x = 80;
            y -= 1;
            checkXY(x, y);
        }
    
        if(x > 80)
        {
            x = 1;
            y += 1;
        }
    
        if(y < 1)
            y = 1;
    }
    
    void CPoint::compare(UINT &val1, UINT &val2) const
    {
        if(val1 > val2)
        {
            UINT tmp = val1;
            val1 = val2;
            val2 = tmp;
        }
    }
    

    Wie ich finde arbeitet diese Version recht schnell wenn man sie RICHTIG verwendet, dennoch macht es mich nachdenklich wenn ich lese : wenn man <multimap> benutzt benutzt kommt viel schneller an die Daten...aber wie gesagt die <vector> version geht auch recht schnell (laut Code::Blocks exec time : 0.000 - 0.014 sec)

    Nun wollte ich euch fragen <vector> oder doch <multimap>?
    Tut mir leid wenn das ganze hier etwas blöde rüberkommt aber ich bin nicht gerade der beste in Sachen STL und kann mich niht entscheiden -.-

    Mfg



  • ist doch ok so...

    oder nicht?

    und wenn du damit zufrieden bist is doch auch alles paletti
    und sollte es dir wirklich so extremst auf geschwindigkeit ankommen geh mal dein rpogramm mit nem profiler durch dann siehste wod er am längsten hängt



  • Hi,
    Danke für deine Antwort 😃

    Ja also um ehrlich zu sein bin ich sehr zufrieden mit meiner Klasse 🙂
    Ok das werde ich mal machen =)... kennst du vllt einen guten Profiler?

    Mfg



  • nein sorry

    wenn ich ehrlich bin hab ich damit acuh noch nie gearbeitet
    aber heir im forum stolperst du öfters mal über diesen begriff und kannst in per suchfunktion finden



  • Hi,
    ist kein Problem...ich hab das gemacht und hab mal den AMD CodeAnalyst besorgt 🙂

    Mfg


Anmelden zum Antworten