Aktuelle Zeit: 18.10.2019 03:13

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: DeleteMapElement()
BeitragVerfasst: 07.09.2019 02:02 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
Habe ich da einen Denkfehler oder steckt da in DeleteMapElement() ein Fehler. Das Löschen der Mapeinträge dauert ca. 40x so lange wie das Anlegen. Das Verhältnis verschlimmert sich sogar noch, wenn ich #cntMax erhöhe.

Code:
EnableExplicit

#cntMax = 30000

NewMap MyMap (#cntMax)
Define time1, time2
Define i


time1 = ElapsedMilliseconds()
For i = 1 To #cntMax
  AddMapElement (MyMap(), "x" + i)
Next
time1 = ElapsedMilliseconds() - time1


time2 = ElapsedMilliseconds()
ForEach MyMap()
  DeleteMapElement (MyMap())
 ;NextMapElement (MyMap())
Next
time2 = ElapsedMilliseconds() - time2


MessageRequester ("", "" + time1 + #CRLF$ + time2)


Wenn ich NextMapElement() auskommentiere, dann stimmen die Zeiten wieder. Allerdings wird dann logischerweise nur jedes zweite Element gelöscht.

Getestet Win7


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 08:42 
Offline
Benutzeravatar

Registriert: 06.07.2014 12:21
Zitat:
Wenn ich NextMapElement() auskommentiere, dann stimmen die Zeiten wieder. Allerdings wird dann logischerweise nur jedes zweite Element gelöscht.


Hallo Josh, ich habe zwar noch nicht Maps verwendetet aber das verhalten sollte ja ähnlich wie von Listen sein,
die Scheife geht doch alle vorhanden Einträge der Map durch, also sollte "DeleteMapElement (MyMap())" doch jeden Eintrag löschen und nicht jeden zweiten.
NextMapElement(Map()) wird ja nicht in einer Foreach schleife verwendet diese ist ja spezial für Maps-listen gedacht sondern in normalen schleifen
EDIT: ok jetzt habe nach dem zweiten mal durchlesen verstanden was was du meinst, aber wenn du alle Einträge Löschen willst warum nutzt du dann nicht ClearMap() ?
Code:
ForEach MyMap()
  DeleteMapElement (MyMap())
 ;NextMapElement (MyMap())
Next

_________________
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 09:04 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
silbersurfer hat geschrieben:
... aber wenn du alle Einträge Löschen willst warum nutzt du dann nicht ClearMap() ?

Im richtigen Programm steht in der ForEach-Schleife noch eine If-Abfrage.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 09:10 
Offline
Benutzeravatar

Registriert: 06.07.2014 12:21
Zitat:
Im richtigen Programm steht in der ForEach-Schleife noch eine If-Abfrage.

Achso, ja dann sieht es so aus das es wirklich an deletemap liegt, denn auch in einer normalen Schleife ist er so langsam.
Code:
  ResetMap(MyMap())
  While NextMapElement(MyMap())
    DeleteMapElement (MyMap())
  Wend

ist auch bei 480 ms

_________________
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 11:41 
Offline

Registriert: 30.03.2011 20:53
Mich würde interessieren, warum das Löschen so extrem viel langsamer ist als das Anlegen der Elemente. Interessant ist nämlich, daß das Löschen der Map-Elemente in einer For-Schleife genauso schnell ist wie das Anlegen der Map-Elemente.

Ein Workaround wäre: Ich sammle zuerst die Keys der Elemente, die ich löschen will, in einer Liste. Danach lösche ich die Elemente mit diesen Keys. Das geht bei mir deutlich schneller.

Code:
EnableExplicit

#cntMax = 30000

NewMap MyMap (#cntMax)
Define time1, time2
Define i

time1 = ElapsedMilliseconds()
For i = 1 To #cntMax
  AddMapElement (MyMap(), "x" + i)
Next
time1 = ElapsedMilliseconds() - time1


time2 = ElapsedMilliseconds()
; ForEach MyMap()
;   DeleteMapElement (MyMap())
;  ;NextMapElement (MyMap())
; Next


; For i = 1 To #cntMax
;    DeleteMapElement(MyMap(), "x" + i)
; Next i


NewList key.s()
ForEach MyMap()
   AddElement(key()) : key() = MapKey(MyMap())
Next
ForEach key()
   DeleteMapElement(MyMap(), key())
Next
FreeList(key())

;Debug MapSize(MyMap())

time2 = ElapsedMilliseconds() - time2


MessageRequester ("", "" + time1 + #CRLF$ + time2)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 12:14 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Josh hat geschrieben:
Wenn ich NextMapElement() auskommentiere, dann stimmen die Zeiten wieder. Allerdings wird dann logischerweise nur jedes zweite Element gelöscht.

Getestet Win7


Die Aussage widerlege ich :
Ich lass dein Beispiel durchlaufen und zeige im MsgReq noch die MapSize mit an.

Code:
ForEach MyMap()
  DeleteMapElement (MyMap())
Next

Anlegen : 4ms
Löschen : 130ms
MapElemente : 0

Code:
ForEach MyMap()
  DeleteMapElement (MyMap())
  NextMapElement()
Next

Anlegen : 4ms
Löschen : 1ms
MapElemente : 15000 (also die Hälfte)

Aber nichtsdestotroz würde ich matbal's Variante wählen, wenn nicht die ganze Map gelöscht werden soll.

_________________
PureBasic 5.71 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 12:21 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Bisonte hat geschrieben:
Josh hat geschrieben:
Wenn ich NextMapElement() auskommentiere, dann stimmen die Zeiten wieder. Allerdings wird dann logischerweise nur jedes zweite Element gelöscht.

Getestet Win7


Die Aussage widerlege ich :

Eigentlich hast Du eher die Aussage bewiesen.
Dieses "auskommentiere" ist das Wort in besagter Behauptung, das glaube ich jeden hier (kurzzeitig) verwirrt hat.
Hätte man auch geschickter formulieren können :lol:

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 15:31 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
HeX0R hat geschrieben:
Hätte man auch geschickter formulieren können :lol:

Ja, hätte man definitiv :lol: Z.b.: ausauskommentieren, entauskommentieren .... :mrgreen:

Das Fatale an der ganzen Gschicht ist, dass die Zeit zum löschen zum Quadrat der Einträge steigt:
Code:
   1k Einträge        1 ms
  10k Einträge       58 ms
 100k Einträge     5606 ms
1000k Einträge   564731 ms


Und was noch komisch ist, mit Debugger geht das löschen ungefähr 25% schneller als bei ausgeschalteten Debugger :|


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 15:34 
Offline
Kommando SG1
Benutzeravatar

Registriert: 01.11.2005 13:34
Wohnort: Glienicke
@Josh:

Das Langsame ist hier nicht das Löschen der Elemente mit DeleteMapElement() sondern das "unnatürliche" durchlaufen der Map mit ForEach oder NextMapElement(). Mit deinem Testcode änderst du sowohl die Anzahl der Slots als auch die Anzahl der Elemente, somit werden zwei Parameter des Tests verändert!

Eine Map ist nun mal keine Liste, somit gibt es keine Verbindung zwischen den Elementen, und daher wird der gesamte Map-Space komplett (jeder Slot) nach Elementen durchsucht.
Daraus folgt logischerweise, dass ForEach MyMap() je länger dauert, je höher die Anzahl der Slots ist, und nicht (nicht nur) je mehr Elemente es gibt.

Du kannst also das Durchlaufen der Map beschleunigen, indem nur nicht so viele Slots reservierst.
Es ist sowieso nicht sinnvoll genauso viele Slots anzulegen wie du Elemente hast, da es so oder so zu Kollisionen kommen kann.
Wenn du Stattdessen nur 1/10 an Slots reservierst, steigt AddMapElement() nur um
etwa 40%, dafür ist "ForEach" halt 10 mal schneller.

Überlege dir noch mal genau, was du eigentlich brauchst:
- Eine Liste mit Verknüpfungen zwischen den Elementen für schnelles Durchlaufen der Liste?
- Ein Array wo es exakt ein Slot pro Element gibt und ein schneller Direkter Zugriff gewährt ist?
- Eine Map bei es eine unbekannte Menge an Elementen Gibt, direkter Zugriff verlangt wird aber kein Durchlaufen der Elemente.

Ich verwende auch gerne Mischformen:
Ich lege eine Map mit den Elementen an und eine Liste mit Pointern zu diesen Elementen (oder auch andersherum). So kann ich beide Vorteile nutzen.

_________________
Bild
 
BildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: DeleteMapElement()
BeitragVerfasst: 07.09.2019 15:44 
Offline
Benutzeravatar

Registriert: 29.08.2004 13:29
Code:
For i = 1 To #cntMax
  DeleteMapElement(MyMap(), "x" + i)
Next

Das ist die schnellste Methode die Elemente einzeln zu löschen ;-)

_________________
Windows 10 / Windows 7
PB Last Final / Last Beta Testing


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye