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

1

21.06.2013, 03:22

QString Zerlegung optimieren

Ich versuche in meinem Projekt das zerlegen eines strings, der 2 Trennzeichen beeinhaltet, zu beschleunigen. Nur anscheinend ist mir das Gegenteil gelungen, und die benötigte Zeit wurde verdoppelt:( (gemessen mit QTime, im Release Mode, nicht über VS gestartet).
Ein, zu zerlegender string, sieht in etwa so aus:
"12:0,15:2,25:4,"

Der Momentane Code sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
void MapReader::_parseTileString(const Point<uint32> &pos, const QString &tileString, Layer layer)
{
    QStringList tileObjectStrings = tileString.split(QRegExp("\\D?,\\D?"));     // beliebig viele nicht digits, gefolgt von einem Komma, gefolgt von beliebig vielen nicht digits
    QStringList::const_iterator itr = tileObjectStrings.begin();
    for (uint32 x = 0; x < m_pMap->getSize().x && itr != tileObjectStrings.end(); ++x, ++itr)
    {
        int delimiterIndex = itr->indexOf(":");
        MapTile tileObject(itr->left(delimiterIndex).toUInt(), itr->right(itr->length() -1 -delimiterIndex).toUInt());
        m_pMap->setMapTile(Point3D<uint32>(x, pos.x, pos.y), tileObject, layer);
    }
}


Meine Trennzeichen sind : und , (nur der Vollständigkeit halber). Hat jemand eine Idee, wie ich das besser optimieren könnte? Eine ähnliche Geschwindigkeit wäre dann schon wünschenswert ;)
Der vorherige Code ist einfach nur scheußlich, und den würde ich ganz gerne weg haben, deswegen suche ich so versessen nach einer besseren Lösung.

PS: Um eventuellen Fragen vorzubeugen. Es geht mir tatsächlich nur um das Zerlegen. Der Rest (das Eintragen in die Map, usw) ist mit der vorherigen Lösung identisch.

EDIT: Nutze QT 4.8.1

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »anti-freak« (21.06.2013, 08:22)


Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

2

21.06.2013, 03:51

Ich würde einfach mal QString::split ausprobieren.

3

21.06.2013, 08:17

Danke für den Tipp. Das hat meine Zeit dann auch wieder halbiert ;)
Habe den Code oben mal aktualisiert, wenn noch jemand was findet, was man verbessern könnte, nur her damit.

mfg

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

21.06.2013, 09:43

Wenn du es wirklich schnell willst, dann darfst du es nicht mit regulären Ausdrücken machen.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

21.06.2013, 10:55

Ich würde zweistufig vorgehen:

1) Split nach komma, führende und folgende Leerzeichen entfernen (Gibt bestimmt trim()-Funktion bei QString)
2) Für jedes Token selber per substring am ":" auftrennen.

Wobei es vielleicht hilft, wenn man die RegEx-ausdrücke vorkompiliert. Aber keine Ahnung, ob das in QT möglich ist - .NET kann das und beschleunigt noch einmal die Auswertung der Ausdrücke.

6

21.06.2013, 21:57

Naja, Geschwindigkeit war jetzt nicht mein Hauptziel, um den Code neu zu schreiben. Allerdings sollte er ihm auch in keiner Weise nachstehen (was er ja jetzt nicht mehr tut), deswegen bin ich eigentlich ganz glücklich.
Aber eigentlich kann ich mir die RegEx auch sparen, da die maps ja eh über meinen Editor erstellt und gespeichert werden, und da wird ohne whitespace gearbeitet.
Hab die RegEx jetzt entfernt, und nochmal einen Geschwindigkeit Boost von ~150-200ms erhalten (bei einer Gesamtdauer von vorher 300-400). Lohnt sich dann schon etwas ;)

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

7

22.06.2013, 12:16

Verstehe ich das richtig, als Format steht fest das immer Zahl:Zahl,Zahl:Zahl kommt? Warum brauchst du dann ueberhaupt 2 verschiedene Trennzeichen?

Abgesehen davon:
Du hast deinen String, mit den ganzen Zeichen drin. Dann hast du einen Counter, der beginnt bei 0.

  1. z1 = 0, z2 = 0
  2. Jetzt erhoehst du den Counter wenn String[Counter] != ':'
  3. wenn nicht, dann z1 = z1 * 10 + String[Counter] - '0' und zurueck zu 2
  4. Counter erhoehen wenn String[Counter] != ','
  5. wenn nicht, dann z2 = z2 * 10 + String[Counter] - '0' und zurueck zu 4
  6. z1 und z2 speichern (das verbraucht dann die ganze Zeit...)
  7. Counter = Counter + 1
  8. Wenn String[Counter] != 0 zurueck zu 1

8

22.06.2013, 13:29

Warum sollte ich keine 2 verschiedenen Trennzeichen brauchen (Das eine dient zum Abtrennen der einzelnen Tiles, das andere zum Abtrennen der einzelnen Tileattribute)?

Und irgendwie verstehe ich auch nur bedingt, was du mir mit deiner Aufzählung sagen möchtest.

Tobiking

1x Rätselkönig

  • Private Nachricht senden

9

22.06.2013, 17:19

Warum sollte ich keine 2 verschiedenen Trennzeichen brauchen (Das eine dient zum Abtrennen der einzelnen Tiles, das andere zum Abtrennen der einzelnen Tileattribute)?

Wenn jedes Tile immer genau ein Attribut hat, dann gewinnst du durch verschiedene Trenner keine Information. Man kann sie auch einfach zählen.

Und irgendwie verstehe ich auch nur bedingt, was du mir mit deiner Aufzählung sagen möchtest.

Ich tippe mal darauf das es zeigen soll, dass es ohne Hilfsmittel möglich ist dein Vorhaben mit einer einzigen Iteration über den kompletten String durchzuführen. Splitten etc. ist da gar nicht nötig. Das

C-/C++-Quelltext

1
z1 * 10 + String[Counter] - '0'

ist die Umwandlung char->int der einzelnen Stellen der Zahlen aus dem String.

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

10

22.06.2013, 20:35

Und irgendwie verstehe ich auch nur bedingt, was du mir mit deiner Aufzählung sagen möchtest.
Das ist Pseudocode, der bei richtiger Umsetzung 10-100 mal schneller sein wird.

Werbeanzeige