Schneller Dateien verarbeiten??

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

Aber wo ist jetzt der große Unterschied? Ich meinte, ich kann das hier nicht ausprobieren, aber für mich sieht das so aus:

Urversion
-> Öffnen
-> Lesen
-> Verarbeiten
->Schließen
->Schreiben

Neue Version
-> Öffnen
-> Lesen
-> In LL schreiben
-> Schließen
-> LL durchgehen
-> verarbeiten
-> Schreiben

Im Endeffekt machst du nur nen Zwischenschritt über den Speicher, ich kann mir gerade nicht vorstellen, warum das so den krassen Geschwindigkeitsunterschied machen soll ö.Ö Ich denke, wenn du den Progressbar wieder einbaust (in den Lesevorgang und den Verarbeitungsvorgang), dass du dann wieder auf einer sehr ähnlichen Geschwindigkeit landen wirst, wie vorher, aber ich kann mich auch irren...

Kann mir das jemand erklären? :?
Ich steh grad echt aufm Schlauch

Gr33tz
Tafkadasom2k5 :freak: :mrgreen:

Edit:
Dein neuer Code...

Code: Alles auswählen

If F_Read(Dateien()\File) > 
   ResetList(ZwischenspeicherDatei())
   FileLength.q = ListSize(ZwischenspeicherDatei()) ;ZwischenspeicherDatei() wurde gerade resettet. FileLength.q = 0?!
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag von Blackskyliner »

Große Dateien werden aber später "besser" verarbeitet.
Bei kleinen Dateien ist beides gleich Schnell, aber die erste Methode wird bei großen Dateien immer langsamer wobei die zweite gleich schnell bleibt. (merkwürdiger Art und Weise), zumindest hab ich das subjektiv so beobachtet.

EDIT
zu deinem Edit, ResetList() setzt nur den Zeiger auf Anfang, was du meinst ist ClearList() ;)
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
sibru
Beiträge: 265
Registriert: 15.09.2004 18:11
Wohnort: hamburg

Beitrag von sibru »

Ich hab´ erhebliche DateiZugriffs-Beschleunigungen mit folgendem Code hingekriegt: (3 bis 16 mal schneller als ReadString()!!!)

Code: Alles auswählen

#PB_Vers  = "4.20"

*MemAdr = AllocateMemory(65536)         ;maxStringSize
FileSize = FileSize(File$)
PB4_FileNr = 1                  ;replace of UseFile()
If ReadFile(1, File$)
  fpos = 0                    ;FilePosPointer (wg. PosCalc mit Happen-Berücksuchtigung
  While FileSize>0
    happen = Min(65536, FileSize)  ;max. StringLen
    ReadData(PB4_FileNr, *MemAdr, happen);Datei(teil) als 64KB-"Happen" einlesen...
    FileBlock$ = PeekS( *MemAdr, happen)  ;...und in String übertragen
    FileBlock$ = ReplaceString(FileBlock$, Chr(10), "") ;ZeilenTrennung: ^10^13 --> ^13
    While FileBlock$>""
      Zeile$ = StringField(FileBlock$, 1, Chr(13)) ;TextZeile separieren
      FileBlock$ = Mid(FileBlock$, Len(Zeile$ + 1)) ;separierte Zeile entfernen

      F01.s = StringField(Zeile, 1, ";"); : Debug F01
      ;       :           :          :      usw...
      F13.s = StringField(Zeile, 13, ";"); : Debug F13

      ;hier F01 bis F13 irgendwie verarbeiten...
    Wend ;FileHappen ready
    fpos + happen
    FileSize - happen
  Wend ;FileSize ready
EndIf

Viel Erfolg !!!
Bild Bild
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag von Blackskyliner »

Mein Problem hat sich soeben erledigt. Hab mir wieder 4.2 Drauf gemacht und es ging wieder alles.

Und die Geschwindigkeit ist jetzt auch Rasant... Ich hatte inen logischen Fehler, woraufhin alles extrem langsam wurde.

Danke an alle die mir geholfen haben. :)

EDIT: ZUdem auch noch ein Danke für diese Art des Auslesens iss sogar noch ein stück schneller geworden, reichlich faszinierend :)
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

@Tafkadasom2k5:

Auch wenn man den Unterschied nicht so wirklich sieht, bei nem 100MB grossem Ascii File ist der Geschwindigkeitszuwachs enorm.

Vielleicht liegts am internen Filehandling.
Ich kann mir vorstellen, wenn 2 Files gleichzeitig geöffnet sind, wird die
FilePosition immer hin und hergeschmissen (Stack rauf Stack runter)
vielleicht ist es deshalb etwas langsamer...

--

Das mit dem Readstringersatz probier ich doch auch gleich mal aus ;)

Aber welche Funktion ist bei Dir Min() ?

Beispiel : happen = Min(65536, FileSize)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

Min ist idR ein Befehl der den kleineren der beiden Werte auswählt. MIN(1,5) gibt also 1 zurück.

Also entweder wird eine Happengröße gelesen, oder wenn der Rest der Datei kleiner ist als eine Happengröße, so wird einfach der Rest ausgelesen.

Genau das, was ich vorhin meinte mit der "guten alten DOS-Optimierung" ;)
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> entweder wird eine Happengröße gelesen, oder wenn der Rest der Datei kleiner ist als eine Happengröße, so wird einfach der Rest ausgelesen

Das stimmt nicht ganz. Man darf zwar den FileCursor nicht hinter das Dateiende setzen, weil es sonst einen Absturz gibt ("Cannot seek beyond EOF"). Man darf aber sehr wohl mit ReadData() 1000 Bytes lesen, selbst wenn der letzte Happen nur 42 Byte groß ist.

Deshalb braucht man den Quatsch mit Min() nicht. Man muss den FileCursor lediglich immer um den Wert weiterschieben, den der Befehl ReadData() zurückgibt.

@ Topic:
Wie wäre es eventuell, wenn du jede Zeile mit Regulären Ausdrücken zerlegst, anstatt mit StringField()? StringField() ist vergleichsweise langsam, denn es durchsucht jedes Mal den String von vorn nach dem Separator.

// Edit
Grad getestet, Reguläre ausdrücke sind ja 20 Mal langsamer als dreizehn Mal StringField() aufzurufen?!?

// // Edit
Wenn man natürlich noch ReplaceString() berücksichtigt, dann sind RegExp's nur 12% langsamer. Zusammen mit dem anderen Klimbin, da mit seiner "NEWLINE$" und so, dürfte es also auf das gleiche hinauslaufen.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Dieses Blockweise lesen ist ja gut und schön, aber wir haben 2009
Heutige Rechner haben mindestens 500 MB, meistens 1 GB und Windows XP und der Rest brauchen ca 200-300 MB. Bleibt also genügend über um eine 100 MB Datei in den Speicher zu laden.

Also rein in den Speicher und dann mit den Windows Memorybefehlen die Datei zerlegen. Falls Interresse kannst auch einen Democode haben.
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Eine Frage, die, wie ich finde, zum Thema passt: Ich würde oft gern die Befehle der RegExp Lib über Speicherbereiche drüber bügeln lassen. Also nicht erst Megabyte große Daten in eine Stringvariable packen und dann dem Befehl übergeben, sondern einfach nur den Pointer zu dem Memory.

Das dürfte die Regulären Ausdrücke doch erheblich beschleunigen, nicht wahr? Kann man das irgendwie bewerkstelligen oder wird das demnächst möglicherweise sowieso in PureBasic eingebaut?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Reguläre Ausdrücke sind so weit ich weis mehr für komplexere Themen,
also erkennen von Sprachen. Da kommen normal auch nicht so große
Dateien vor. Du merkst doch schon beim Compilieren, wie lang es dauert
50.000 Zeilen zu kompilieren. Ich würd es auch so machen wie hjbremer.

- Datei öffnen
- Dateigröße bestimmen
- Speicher für die gesamte Datei reservieren
- Datei komplet in einem rutsch in den Speicher lesen
(bei 100 MB dauert das 2-5 Sekunden bei "normalen" Festplatten)
- Mittels CompareMemoryString() und PeekX() die Daten parsen und auslesen

Das ist die schnellste theoretische Möglichkeit. Und wenn du es richig
machst auch in der Praxis. :mrgreen:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten