Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Nimelrian

Alter Hase

  • »Nimelrian« ist der Autor dieses Themas

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

41

15.03.2014, 13:15


In Zeile 11 dereferenzierst du hier dein tex nachdem du aus ihm gemoved hast. Das ist keine gute Idee. Wenn du aus einem std::unique_ptr movest, wird der originale unique_ptr zu nullptr...


Das habe ich bereits ausgebügelt, ist mir selbst direkt aufgefallen. Die anderen Vorschläge implementiere ich auch noch, soweit ich kann, und poste dann den aktuellen Stand, könnte aber etwas dauern :)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

42

15.03.2014, 14:41

Das wichtigste, was du meiner Meinung nach aus diesem Beitrag lernen kannst ist, dass du erst versuchen solltest ein Problem so einfach und schnell(im Bezug auf den Zeitaufwand bei der Entwicklung) wie möglich zu lösen. Sollten dir später Performanceprobleme auffallen, kannst du dich dann darum kümmern. Optimierungen, die buggypixels vorschlägen ähneln, können viele Nachteile haben. Der Aufwand sollte immer in einem guten Verhältniss zum Nutzen stehen. Optimierungen bis ins kleinste Detail dauern lange und lohnen sich an den meisten Stellen nicht, weil sie viel zu selten ausgeführt werden. In der Regel werden ca. 20% des Codes in 80% der Zeit ausgeführt. Es ist Unsinn die anderen 80% zu optimieren. Solche Optimierungen können unerwartete Fehler enthalten, was wieder Zeit und Mühe kostet(in diesem Thread waren es die Hash-Kollisionen). Du kannst dir auch nur selten sicher sein, ob eine Optimierung den gewünschten Effekt hat, solang du nicht die Alternative testest. Ausserdem weißt du während der Entwicklung nicht ob dein Ressourcenmanager falsch verwendet wird oder falsch konzipiert ist oder ob mit deinem optimierten, aber viel komplexeren Code etwas nicht stimmt. Zuguterletzt benötigt man sehr viel Erfahrung um mit C++ jede Nanosekunde herauskitzeln zu können. Gut, dass das bei den meisten 2D-Desktop Spielen heutzutage kaum noch von Interesse ist, weil unsere Rechner sowieso dabei einschlafen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Nimelrian

Alter Hase

  • »Nimelrian« ist der Autor dieses Themas

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

43

17.03.2014, 17:56

Oh und anstatt die Map effektiv zweimal zu traversieren (einmal beim initialen find() und einmal beim insert() falls nichts gefunden wurde), könnte man einfach per [] Operator in der Map nachschauen und sich zunutze machen, dass der [] Operator im Falle, dass nichts gefunden wird, ein default-konstruiertes Objekt einfügt und dieses returned... ;)

Problem bei [] ist allerdings, dass ich hier nicht überprüfen kann, ob die Textur schon geladen wurde. Ich habe daher nun at verwendet, welches eine Exception wirft, wenn das Element noch nicht vorhanden ist. Das catche ich einfach und füge dann per insert ein.
Funktioniert nach ersten Tests wunderbar.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Texture* ResourceManager::getTexture(const std::string& filename) {
    try {
        return resourceMap.at(filename).get();
    }
    catch (const std::out_of_range& e) {
        std::unique_ptr<Texture> texInsert(new Texture);
        Texture* tex = texInsert.get();
        if (!(texInsert->loadFromFile(resourcePath + filename))) {
            throw ("The file \"" + filename + "\" can not be found at " + resourcePath + "!");
        }
        resourceMap.insert(std::make_pair(filename, std::move(texInsert)));
        return tex;
    }
}


resourceMap ist jetzt auch eine std::unordered_map.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Nimelrian« (17.03.2014, 18:25)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

44

17.03.2014, 18:22

Das Zitat ist aber nicht von mir. ^^
Edit: das hätte ich auch als PM schreiben können. Zu spät. :rolleyes:
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Nimelrian

Alter Hase

  • »Nimelrian« ist der Autor dieses Themas

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

45

17.03.2014, 18:30

BC mag Exceptions für den Control Flow nicht, also die (hoffentlich) endgültige Version:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const Texture* ResourceManager::getTexture(const std::string& filename) {
    auto texIt = resourceMap.find(filename);

    // No texture with the given filename was found, load it and move the pointer into the map
    if (texIt == resourceMap.end()) {
        std::unique_ptr<Texture> tex(new Texture);
        if (!(tex->loadFromFile(resourcePath + filename))) {
            throw ("The file \"" + filename + "\" can not be found at " + resourcePath + "!");
        }
        resourceMap.insert(std::make_pair(filename, std::move(tex)));
        return resourceMap.find(filename)->second.get();
    }
    // Texture is in the map already, return it
    else {
        return texIt->second.get();
    }
}
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

46

17.03.2014, 18:31

So ist es auch völlig ok, selbst wenn du 2mal traversierst. Denn du traversierst nur 2mal, wenn du ein Bild aus einer Datei lädst. Damit ist es verhältnismäßig so oder so irrelevant, selbst wenn du noch ein paar mal mehr komplett durchlaufen würdest.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

47

17.03.2014, 18:32

Ja, Exceptions sollte eigentlich wirklich nur für Ausnahmefälle sein. Oft sind sie auch alles andere als schnell ...
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Nimelrian

Alter Hase

  • »Nimelrian« ist der Autor dieses Themas

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

48

17.03.2014, 18:46

Nochmal etwas hübscher/performanter, ohne find:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const Texture* ResourceManager::getTexture(const std::string& filename) {
    auto texIt = resourceMap.find(filename);

    // No texture with the given filename was found, load it and move the pointer into the map
    if (texIt == resourceMap.end()) {
        std::unique_ptr<Texture> tex(new Texture);
        Texture* retTex = tex.get();
        if (!(tex->loadFromFile(resourcePath + filename))) {
            throw ("The file \"" + filename + "\" can not be found at " + resourcePath + "!");
        }
        resourceMap.insert(std::make_pair(filename, std::move(tex)));
        return retTex;
    }
    // Texture is in the map already, return it
    else {
        return texIt->second.get();
    }
}
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

Werbeanzeige