Seite 1 von 1

Dateierstellung und Füllung ziemlich langsam

Verfasst: 12.08.2016 01:43
von Delle
Hallo,

ich habe eine Datei "Wörter.txt" mit ca. 1,5 Millionen Wörtern.

Ich will in dieser Datei jetzt zeilenweise jedes Wort auslesen, den Anfangsbuchstaben ermitteln und dementsprechend in [Anfangsbuchstabe].txt alle Wörter mit diesem Anfangsbuchstaben schreiben.

Das hier funktioniert einwandfrei, ist aber selbst nach einer Stunde gerade mal beim Buchstaben F angekommen:

Code: Alles auswählen

Enumeration
  
  #Fenster
  #Start
  #Name
  
EndEnumeration

InitNetwork()

OpenWindow(#Fenster,0,0,490,510,"...",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)

ButtonGadget(#Start,10,440,470,30,"Umwandlung starten")

TextGadget(#Name,10,480,470,20,"",#PB_Text_Center)


  Repeat 

		
		EventID = WaitWindowEvent()
     
		If EventID=#PB_Event_CloseWindow:End:EndIf
		
		If EventID=#PB_Event_Gadget And EventGadget()=#Start
		  
		  
 		  If ReadFile(1,"Wörter.txt")
 		    
 		    While Eof(1)=0
          
          aktuell$=ReadString(1)
          
          first$=Left(aktuell$,1)
          
          OpenFile(99,Left(aktuell$,1)+".txt",#PB_File_Append)
          WriteStringN(99,aktuell$,#PB_Ascii)
          CloseFile(99)
          
            
          aktuell$=""
            
          While WindowEvent():Wend
           
        Wend
        
     CloseFile(1)
     
     
   EndIf
		  
	EndIf
     
ForEver
Wieso ist das so langsam? Sollten vielleicht gleich 26 Dateien mit den jeweiligen Anfangsbuchstaben erstellt und auch offen gehalten werden?

Danke!

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 12.08.2016 01:54
von matbal
Das ständige Öffnen und Schließen der Datei bremst stark.

Ich würde einmal erstellte Dateien geöffnet lassen und mir merken, welche Dateien schon geöffnet sind. Das sollte das Geschwindigkeitsproblem beseitigen.

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 12.08.2016 09:43
von NicTheQuick
Lies alle Wörter in eine LinkedList, sortiere sie und schreibe dann erst alle Wörter mit A in die erste Datei, dann B in die zweite, usw. Durch die Sortierung kommen sie alle der Reihe nach dran und du musst nicht zwischendurch die Dateien wechseln.
Ansonsten ist es natürlich auch eine gute Idee alle 26 Dateien einfach offen zu halten. Denn ständiges Öffnen und Schließen macht alles sehr langsam.

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 13.08.2016 18:27
von Rudi
Außerdem würde ich eine so große Datei mittels "ReadData()" in den Speicher lesen...

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 14.08.2016 00:59
von Bisonte
Da ich annehme, daß Du am Ende mit den einzelnen Wörtern in den Dateien später noch was vorhast,
würde ich glatt sagen, das die Wörter in eine Datenbank gehören.

Dort kann man dann bequem und relativ performant die einzelnen Wörter suchen...

Nur mal so als Anregung...

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 14.08.2016 12:13
von xdes
hi,

hemm meine idee ist wenn die festplatte schnell genug das das ganze in zwei bis 3 treads zu teilen...

und wie schon genant so wenig wie möglich die Datei neu inialitzieren...

dabei würde ich thread 1 zum lesen machen tread 2 zum bearbeiten und thread 3bis x zum ausgeben und speichern

beispiel:
thread 1 die lese datei gelesen(nur einmal öffnen) in
thread 2 so was wie left() gemacht
thread 3-x das schrieben in die datei (ein thread/aktion)

wenn es dabei stärker Überschneidungen gibt würde ich vermutlich ein array als cache verwenden (dabei kommt es aber auf die zu lesenden Größen an )

wenn du es nicht direkt ein File System brauchst und noch andere Parameter brauchst ist dabei evtl auch eine db interessant...
desweiteren kann auch das eine oder andere AV und ähnliches deine Festplatte langsamer machen oder die Zugriffs Geschwindigkeit verlangsamen (evtl hilft da ein blick mal (in Windows) in den perfmon und dann zu gucken wie viel das dann wirklich nutzt...


mit freundlichen grüßen

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 14.08.2016 20:48
von NicTheQuick
Bei Festplatteninteraktion sind Threads ziemlich überflüssig und wahrscheinlich sogar eher kontraproduktiv. Die Festplatte ist da schließlich immer noch der Flaschenhals. Damit wird also nichts schneller. Und solche kleinen Aufgaben auf verschiedene Threads aufzuteilen und diese dann zu synchronisieren, macht es vermutlich langsamer als wenn man es direkt in einem Thread macht.

Re: Dateierstellung und Füllung ziemlich langsam

Verfasst: 15.08.2016 17:05
von matbal
Jetzt war ich doch mal neugierig, wie lange das aussortieren dauert. Das einzige, was ich anders mache, ist, ich lasse alle Zieldateien geöffnet.
Auf meinem Computer (Dual-Core Celeron) dauert es bei einer Größe von 1500000 Pseudo-Wörtern ca. 2 Sekunden.

Das ist der Code, mit dem ich die Wörter aufteile.

Code: Alles auswählen

Define InFile$ = "c:\temp\test.txt"
Define OutPath$ = "c:\temp\"

Global NewMap fn()            ; Dateinummern 
Define zeile$, a$ 


If ReadFile(0, InFile$)
   While Not Eof(0)
      zeile$ = ReadString(0)           ; Wort lesen
      
      a$ = Left(zeile$, 1)             ; Anfangsbuchstabe
      
      If fn(a$) = 0
         fn(a$) = CreateFile(#PB_Any, OutPath$ + a$ + ".txt")
      EndIf
      
      WriteStringN(fn(a$), zeile$)     ; Wort in Datei schreiben
   Wend
   CloseFile(0)
   
   
   ForEach fn()                   ; Alle Dateien schließen
      CloseFile(fn())
   Next
EndIf

Und hier noch der Code zum Erstellen der Test-Datei mit den 1500000 Pseudo-Wörtern.

Code: Alles auswählen

Define File$ = "c:\temp\test.txt"

Define maxlen = 20
Define minlen = 3
Define wortanz = 1500000

Define wort$, rndlen, *c.character, i, n 


wort$ = Space(maxlen)            

If CreateFile(0, File$)
   
   For i = 1 To wortanz
      rndlen = Random(maxlen, minlen)    
      
      *c = @wort$                         
      For n = 1 To rndlen
         *c\c = Random('z', 'a')          
         *c + SizeOf(character)           
      Next n
      *c\c = 0                            
      
      WriteStringN(0, wort$)              
   Next i
   
   CloseFile(0)
EndIf