Hallo,
ich habe einen QHash der einen QString als key und einen Pointer einer Klasse als value aufnimmt. Während der Laufzeit erzeuge ich mit new Objekte und speichere dann die Pointer im Hash. Wenn ich mit dem Hash fertig bin bzw mit den Daten gearbeitet habe möchte ich diese löschen bzw den Speicher wieder freigeben. Das mache ich folgendermaßen :
Wenn größere Datenmengen verarbeitet werden, also der Hash mehrere Tausend Objekte speichert dauert das löschen des Hashs sehr sehr lange. Nun stelle ich mir die Frage ob es nicht vllt eine schnellere, performantere Methode gibt den Hash und dessen Inhalt zu löschen. Über eure Hilfe würde ich mich freuen.
Nein, gibt es nicht. qDeleteAll() geht auch nur über alle Elemente drüber. Die Abfrage auf isEmpty() ist blödsinnig und QHashIterator ist etwas langsamer als der stl-Iterator von QHash (siehe Doku), delete k.next().value() sollte auch gehen. Aber ich denke eher die Zeit geht beim delete drauf. Mit valgrind/callgrind kann man da genauer schauen.
Ich weiss nicht wie Performant das im Gegenzug ist - müsstest du mal testen. Sollte ein tick langsamer sein als die STL iteratoren, da erst eine Liste vom values aufgestellt wird (zumindest wenn das intern über ebenso über STL::iteratoren läuft, wenn die da einen Trick benutzen kanns schneller sein).
Wenn es zeitkritisch ist und du nen Mehrprozessor hast, wie wäre es hiermit? (pseudocode)
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_RVCT)
/* make use of typeof-extension */
template <typename T>
class QForeachContainer {
public:
inline QForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
const T c;
int brk;
typename T::const_iterator i, e;
};
#define Q_FOREACH(variable, container) \
for (QForeachContainer<__typeof__(container)> _container_(container); \ /* geinlinter Konstructor, implict data sharing -> Kopiert datenpointer */
!_container_.brk && _container_.i != _container_.e; \ /* .brk==0 und .begin(bzw laufindex) != .end() */
__extension__ ({ ++_container_.brk; ++_container_.i; })) \
for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))
#else
/* egal */
Ohne Compileroptimierung ist das wohl etwas langsamer als gleich die STLiteratoren zu nehmen da zumindest ein Pointer mehr kopiert wird ... ich hab noch nie valgrind benutzt, mag mir jemand sagen wie man das (ca) damit testen könnte? Weiss jemand was das _container_.brk; machen soll? Ich würde mal "vermuten" das es bei "break" nochmals incrementiert (oder nicht dekrementiert) wird und dann für den schnellen ausstieg aus schleife 1 sorgt? Ich nehme mal an das __extension__ durch den Rumpf des foreach's ersetzt wird?