IO Performance von memoread, filestr und Low Level Funktione

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Bitmusterschuster
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 42
Registriert: Do, 12. Feb 2009 11:30
Danksagung erhalten: 2 Mal

IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Bitmusterschuster »

Hallo Allerseits,

ich bin neu im Forum. Mein Name ist Rudi (manchmal ratlos)
Ich entwickle seit 20 Jahren in Clipper und seit 1 Jahr in Xbase++

Ich habe ein Problem mit der Geschwindikgkeit von IO Funktionen, wie memoread(), FileSrt() und Fwrite() etc.
In meinem Programm lese ich Textdateien mit Memoread() in eine Variable cText.
Dort tausche ich mit strtrans() die Chr(13)+chr(10) Werte (Cr Lf) gegen einen HTML-Tag <BR> aus.
Danach schreibe ich den Text in eine CSV-Datei, die ich gerade mit Daten aus einer DBF-Datei fülle.

Mein Problem ist, dass der Vorgang des Auslesens der Textdatei mit Memoread() auf manchen Rechnern bis zu 4 mal langsamer läuft, als bei mir oder manchen anderen Kundenrechnern.
Alle Rechner arbeiten im Netzwerk unter Windows 2003 Servern. Die gleichen Performanceunterschiede habe ich, wenn ich statt memoread() die low Level Funktionen fopen() fread() und fclose() verwende. Ebenso bei Filestr().
Es schein so zu sein, dass das Öffnen und Schließen der Dateien in manchen Umgebungen länger dauert.

Könnte ihr mir vielleicht sagen, an welcher Schraube (Registry ?) ich drehen muss, um die Performance zu steigern ?

Vielen Dank für die Hilfe

Rudi
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9384
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Tom »

Hallo, Rudi.

Willkommen im Forum!

Ich würde da eine Ursache außerhalb von Xbase++ vermuten, z.B. einen Virenscanner, der beim Lesen von Dateien scannt und den Prozess dadurch verzögert (Ausnahmeliste unzureichend bestückt?). FileStr() liest eine Datei am Stück ein (es sei denn, man parametrisiert die Funktion anders) - und nach meiner Beobachtung auch sehr große Dateien ziemlich fix, selbst von einem Netzwerkserver. Vielleicht lohnt es sich, mal auszuprobieren, was passiert, wenn man die Datei auf ein lokales Laufwerk kopiert und von dort liest. Ich hatte mal ein Problem mit sehr großen .XPF-Dateien, weil _SymLoad() (die eigentliche Funktionalität von "RESTORE FROM") tatsächlich jede einzelne Variable einzulesen scheint, weshalb ich dazu übergegangen bin, diese Dateien ins lokale Temp-Verzeichnis zu kopieren und von dort zu laden. Dramatischer Geschwindigkeitsgewinn.
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9384
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Tom »

Ergänzung: Mit einem Tool wie "Procmon" kann man sehr schön beobachten, welche Anwendungen welche Dateien anfassen und zu welchen Verzögerungen es kommt. Wenn man das Tool so einrichtet, dass es ein bestimmtes Verzeichnis beobachtet, kann man relativ leicht herausbekommen, warum Lese- und Schreibvorgänge verzögert stattzufinden scheinen. Das Tool gibt es kostenlos hier:

http://technet.microsoft.com/en-us/sysi ... 96645.aspx
Herzlich,
Tom
Bitmusterschuster
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 42
Registriert: Do, 12. Feb 2009 11:30
Danksagung erhalten: 2 Mal

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Bitmusterschuster »

Hallo Tom,

vielen Dank für deine schnelle Antwort.
Ich habe mir Procmon schon heruntergeladen und werde es mal ausprobieren, ob ich da was erkennen kann.
Die Idee mit dem lokalen Laufwerk habe ich schon ausprobiert, es war natürlich viel schneller, als auf dem Netzlaufwerk. Wenn es die Logik zulässt, mache ich das auch schon so. In diesem Fall ist es aber so, dass es sich um Dateien handelt, die nur auf einem Serverlaufwerk liegen können, da sie von jedem User geändert und aufgerufen werden können. Es handelt sich um TXT-Dateien, die eine Inhaltsangabe zu einem Videofilm beinhalten. Ich werde mal versuchen, ob ich die Texte in Memofelder packe, und diese dann schneller auslesen kann, als mit den Fileread-Befehlen von Xbase++.

Herzlichen Dank
Rudi
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16534
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 112 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Martin Altmann »

Hallo Rudi,
was Tom meinte:
  1. Datei lokal kopieren
  2. lokale Kopie lesen
  3. lokale Kopie löschen
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9384
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Tom »

Hallo, Rudi.
Ich werde mal versuchen, ob ich die Texte in Memofelder packe
Damit dürftest Du Zugriff und Verwaltung deutlich vereinfachen. Memofelder in Xbase++ sind nicht längenbegrenzt, und da HTML-Tags auch plain ASCII sind, sollte es damit ebenfalls keine Probleme geben. Übrigens lassen sich auch RTF-Texte wohlfeil in Memos speichern. Bei allen anderen Formaten (DOC, PDF usw.) sollte man auf FOXDBE wechseln und BLOB-Felder nutzen - oder die Binärdaten beim Schreiben z.B. mit Str2Hex() und beim Lesen umgekehrt mit Hex2Str() umwandeln. Aber auch all das lässt sich prima in Tabellen schreiben. :wink:
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12911
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von AUGE_OHR »

hi,
Bitmusterschuster hat geschrieben: Alle Rechner arbeiten im Netzwerk unter Windows 2003 Servern.
...
Könnte ihr mir vielleicht sagen, an welcher Schraube (Registry ?) ich drehen muss, um die Performance zu steigern ?
such mal nach Opportunistic locking im Forum ...
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9384
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Tom »

@Jimmy: OpLocking bei Low-Level-Dateioperationen? Meinst Du wirklich? :o

Das müsste sich dann auch im normalen DBF-Zugriff zeigen.
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12911
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von AUGE_OHR »

hi,
Tom hat geschrieben:@Jimmy: OpLocking bei Low-Level-Dateioperationen? Meinst Du wirklich? :o
Das müsste sich dann auch im normalen DBF-Zugriff zeigen.
ausprobieren ...
wenn ich W2Kxxx lese denke immer erstmal an Op´s Lock ...

tja, jetzt müsste man ein kleines "Performance" Programm zu Hand haben ... ein Registry Tools
so wohl "on Bord" sein :)
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9384
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Tom »

OpLocking ist wirklich nur bei konkurrierenden Dateizugriffen relevant (und spürbar), und die finden ja definitiv nicht statt, wenn man in eine Textdatei schreibt oder in ihr liest. Hier dürfte der Programmierer dafür gesorgt haben, dass nicht zwei oder mehr Nutzer das gleichzeitig mit derselben Textdatei tun. :wink:
Herzlich,
Tom
Bitmusterschuster
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 42
Registriert: Do, 12. Feb 2009 11:30
Danksagung erhalten: 2 Mal

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Bitmusterschuster »

Hallo Allerseits,

ich hatte im Vorfeld natürlich schon Alles in Sachen Op-Locking ausprobiert. Das Programm von Auge_ohr hab ich natürlich auch benutzt, um die diversen Schlüssel einzustellen. Das wirkt sich aber bei mir nicht aus.
Erstens, weil ich ADS 9.0 benutze und nicht den DBFCDX-treiber von Alaska, und auf die low Level Funktionen hatte es keinen Einfluss.

Ich habe es jetzt tatsächlich mit Memodateien gemacht. Über ein kleines Tool habe ich die TXT Dateien in die Memofelder kopiert. Der Datenexport ist jetzt ca. 5 mal schneller geworden. Ich benötige jetzt für 56000 Artikelstammsätze im Netz noch ca. 40 Sekunden um daraus eine 46 MByte große CSV-Datei zu machen.

Ich bin zufrieden und Danke euch fürs Mitdenken.

Bis zum nächsten Problem ...

Herzlichst
Rudi
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15698
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von brandelh »

Bitmusterschuster hat geschrieben: Ich werde mal versuchen, ob ich die Texte in Memofelder packe, und diese dann schneller auslesen kann, als mit den Fileread-Befehlen von Xbase++.
Hallo,

also wenn du

Code: Alles auswählen

cTxt := memoread(cFileName)
nutzt, dann hast du definitiv den schnellsten Weg eine Datei einzulesen.
Allerdings wird diese Textdatei nicht vor dem Überschreiben anderer Stationen geschützt - falls das ein Problem ist.
Lokal bringt eine moderne Festplatte meist über 30 bis 40 MB pro Sekunde, teilweise deutlich mehr.
Im Netzwerk wird der Server sicher schon beschäftigt sein wenn du mit deinem Auftrag ankommst und bei einem 100MBit Netzwerk sind nicht mehr als 10 MB/sek. drin.

Wie groß sind denn die Dateien ?
Was machst du nach dem Einlesen ? Nutzt du Memoline() ? Für sehr kleine Dateien (bis 20 KByte) ist das OK, ansonsten :evil:
Ich lese im Büro Dateien lokal bis zu 1 GigaByte ein, was nur wenige Sekunden braucht, solange der Arbeitsspeicher doppelt so groß wie die Datei ist (ich habe 2 GByte).
Gruß
Hubert
Bitmusterschuster
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 42
Registriert: Do, 12. Feb 2009 11:30
Danksagung erhalten: 2 Mal

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von Bitmusterschuster »

Hallo Hubert,

ich habe zu den Artikeldatensätzen von Multimediaprodukten die Rezension (Inhaltsangabe eines Films z.B.) in externen Textdateien abgelegt.
Der Kunde kann mit Memoedit diese Dateien editieren.
Über die Artikel-Id sind die Texte mit den Artikeldatensätzen verknüpft. Das ist soweit alles bewährt und ok.
Ein Kunde wünschte nun den Export dieser Daten. mitsamt den Texten, auf einen externen FTP-Server.
Also habe ich in der ersten Version einen CSV-Export der Felder der Datenbank geschrieben, und in diesem Zusammenhang die Textdateien pro Datensatz mit Memoread (cTxt) gelesen. Nach dem Lesen habe ich den Text mit strtrans() bearbeitet und die CrLf und CHR(141) Zeilchen in <BR> Tags gewandelt, da der Kunde die Daten für seinen I-Shop in HTML-Formatierung benötigte.

Das funktionierte bei mir im Einplatzbetrieb sehr gut (ca. 500 Datensätze pro Sekunde) Bei einem Kunden im Netzbetrieb schaffte ich fast die gleiche Performance, nur bei einem anderen Kunden lief die Sache erheblich langsamer, obwohl er auch einen sehr schnellen W2003-Server (4 Kerne) und eine relativ neue Netzwerkinfrastruktur hatte. Ich fand nur nicht heraus, warum es bei dem einen Kunden im Netz schneller lief, als bei anderen Kunden.
Es stellte sich heraus, dass ausschließlich das Lesen der Txt-Datein zu dieser Verzögerung geführt haten, nicht etwa die strtrans() Operationen. Ich habe dann mit allen anderen IO-Funktionen gearbeitet (StrFile(), Fopen(), Fread() etc.) aber das Ergebnis war immer gleich. OPLock Einstellungen wie sie Auge_Ohr beschreiben hat, habe ich ebenfalls alle ausprobiert. (zumindest auf der Workstation)

Letztendlich habe ich mir überlegt, die Texte einfach in Memofelder zu packen. Dieses Verfahren habe ich aus schlechten Erfahrungen unter Dbase und Clipper in den 80er Jahren immer gemieden, aber es klappte hervorragend. Das Programm lief logischerweise 5-6 mal schneller im Netz.

Da ich ADS 8.1 beim Kunden einsetze, habe ich die Sache dann noch in einen komplexen SQL Befehl gepackt und der Export läuft nun im Netz mit ca. 60 Sekunden für 56000 Artikelstammsätze incl. Textexport super schnell. Vorher benötigte das Programm mehr als 20 Minuten für die gleichen Artikel.
Das Problem beim SQL Befehl war nur, dass ein Memofeld nicht einfach in einem Group by Befehl gepackt werden kann, den ich aber benötigte. Ich habe dann das Memofdeld mit convert(cFeld,SQL_VARCHAR) umgewandelt, und konnte es dann im SQL-Befehl benutzen.

Letztendlich wollte ich mit dieser Anfrage nur klären, warum die IO-Befehle auf manchen Netzwerken wesentlich langsamer laufen.

Danke für die zahlreichen Kommentare. Tolles Forum hier ...

Schönes Wochenende an Alle
Rudi
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15698
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: IO Performance von memoread, filestr und Low Level Funktione

Beitrag von brandelh »

Hi,

gut wenn es bei dir nun geklärt ist, ich würde fast - wie TOM - auf einen Virenscanner tippen, der alle TXT Dateien die geöffnet werden durchscannt, während der beim anderen Kunden dieses grundsätzlich nicht tut oder die TXT Dateien ausgenommen hat.
F-Prot hier z.B. musste ich beibringen, dass er DBF und DBT Dateien nicht scannen soll ...

Wenn es nun funktioniert ist das gut.
Gruß
Hubert
Antworten