Map oder nicht Map, das ist hier die Frage...



  • Hi,

    ich bin dabei meinen Texturmanager zu Optimieren, bisher habe ichs immer so gemacht:

    class TextureObject
    {
    public:
    	unsigned int 	textureHandle;
    	unsigned int 	width;
    	unsigned int 	height;
    	unsigned int	bpp;
    
    	char		fileName[48];
    };
    

    Davon hab ich diverse Objekte (pro Textur 1) in einen Vector gestopft und den Vector durchlaufen lassen nach Namen um das Handle zu bekommen auf die Textur.

    Ein Kumpel meinte ich könnte das mit einer std::map lösen, doch ist das so von vorteilhaft? Ist das so gut? Wie benutze ich std::map für meine Zwecke? 😕



  • genau mein bereich 😉

    ok, maps sind verdammt vorteilhaft:

    //pseudocode
    Texturmanager.insert(Texturename,Texture);
    Texture=Texturemanager.getTexture(Texturename);
    

    man kann mit map die texturen mittels ihres dateinamens identifizieren, was sehr vorteilhaft ist, wenn man zb mit DirectX effekten arbeitet, da man in einem Effekt ja auch den namen einer Textur unterbringen kann.
    so kann man alle benötigten informationen da drin integrieren, und beim laden einfach den dateinamen abfragen 😉

    achja, so sieht die passende map aus:

    std::map<string,Textur> Container;
    


  • eine map ist immer dann sinnvoll wenn du ein einem Wert hast und einen anderen Wert nachzuschagen. Eine map ist ein assoziativer Container. Ein anderes Beispiel für solch ein Container wäre ein Array, man hat ein int und kann damit einen Wert nachschlagen, allerdings kannst du auch dadurch iterieren. Bei einer map hast du auch begin() und end().

    Mit einer map kannst du aber jeden Type A mit irgend einem Wert b einem anderen Type C mit irgend einem Wert d zuweisen, solange C mit einem < Operator ausgerüstet ist.

    map<A,C>e;
    e.insert(make_pair(b,d));
    //...
    e.find(b)->second==d
    

    oder

    map<A,C>e;
    e[b]=d;
    //...
    e[b]==d
    

    Ersteres bevorzuge ich zwar da e[b] ein Object erstellt wenn es noch kein b gibt.



  • @otze:
    also kann ich z.B. folgendes machen:

    class TextureObject
    {
    public:
        unsigned int     textureHandle;
        unsigned int     width;
        unsigned int     height;
        unsigned int    bpp;
    };
    
    // name, objekt
    std::map <std::string, TextureObject> myMap;
    

    Oder wäre das noch nicht gut genug? 😕



  • Du brauchst noch ein < Operator für TextureObject. (In einer map sind die Objekte sortiert um schneller auf sie zugreifen zu können).



  • nochwas zum stil: in KLASSEN sind variablen niemals public, für solche fälle in denen man nur public sachen hat, sollte man structs nehmen-dafür sind sie da 😉



  • Irgendwer schrieb:

    Du brauchst noch ein < Operator für TextureObject. (In einer map sind die Objekte sortiert um schneller auf sie zugreifen zu können).

    Warum? Das gilt doch nur für den Schlüssel.



  • otze schrieb:

    nochwas zum stil: in KLASSEN sind variablen niemals public, für solche fälle in denen man nur public sachen hat, sollte man structs nehmen-dafür sind sie da 😉

    Also wäre das "Design" wie ich es gepostet habe, effektiv? 😕



  • Hallo,

    schnelle Container ? hash_map ?



  • ja was issn das schon wieder? 😞 was issn nun am schnellsten und wie gestalte ich es am effektivsten? 😞 *keinen peil mehr hab*



  • Hallo,

    das funktioniert genauso wie ne Map vom Interface her. Ist leider nicht bei jeder STL vorhanden. Ich weiss nicht ob es trotzdem Standard ist.

    Jedenfalls erfolgt der Zugriff über Hashtabellen, du hast zwar im worst case immer noch Komplexität O(n) wenn du nen Überlauf hast, aber in der Regel ist die Komplexität für den Zugriff bzw. Lookup O(1).

    Wenns also schnell gehen soll ne gute Wahl denke ich. In ner Hashmap sind die Werte nicht geordnet aber das ist ja auch nicht nötig wegen der Zugriffsart.



  • hash_map kenn ich auch net, habs auch nicht nachschlagen können,muss irgendwas spezielles aus ner andren lib sein^^

    //edit aha, das is also ne hash_map..
    um wieviel schneller ist die denn? die normale map ist ja schon logarithmisch, viel mehr sollte da doch garnich gehen oder?
    und was bedeuted eigentlich o(n)/o(1) ist das irgendein mathematisches symbol(googlen kann man danach leider nicht,habs ausprobiert^^)



  • also was soll ich denn nun nehmen und wie designe ich das am besten? 😕



  • du nimmst jetzt std::map und machst die Membervariablen deiner Klasse private



  • [Edit]siehe nächster Beitrag. Doppelposting[/Edit]





  • thx, war sehr aufschlussreich 😉



  • Hallo,

    schnelle Container ? hash_map ?

    Ist nicht standart und nur schneller wenn man sehr wenige Objekte hat. Der einzige unterschied zu map ist, dass die elemente nicht geordnet werden.

    Warum? Das gilt doch nur für den Schlüssel.

    Sorry, zu schnell gepostet. Das gilt natürlich nur für den Schlüssel.



  • Irgendwer schrieb:

    Hallo,

    schnelle Container ? hash_map ?

    Ist nicht stan**** und nur schneller wenn man sehr wenige Objekte hat. Der einzige unterschied zu map ist, dass die elemente nicht geordnet werden.

    Das ist AFAIK nicht der einzige Unterschied. Der lookup geschieht per Hashtabelle sprich direkte Addressierung der Elemente im Container.
    Deswegen komplexität O(1) also konstant, wenn man vorraussetzt dass die Schlüssel in konstanter Zeit tranformiert werden können.
    Wenn du mit "wenige Einträge" meinst, dass die Anzahl der zu speichernden Schlüssel klein im vergleich zum Schlüsselraum ist, stimmt dass natürlich.
    Das ist im konkreten Beispiel der Fall.

    Das es nicht Standard ist, hab ich jetzt auch nachgelesen und ja bereits gesagt dass ich im Moment des Postings nicht wusste ob es Standard ist.


Anmelden zum Antworten