IO Performance von memoread, filestr und Low Level Funktione
Moderator: Moderatoren
-
- 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
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
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
- Tom
- 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
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.
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
Tom
- Tom
- 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
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
http://technet.microsoft.com/en-us/sysi ... 96645.aspx
Herzlich,
Tom
Tom
-
- 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
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
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
- Martin Altmann
- 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
Hallo Rudi,
was Tom meinte:
Martin
was Tom meinte:
- Datei lokal kopieren
- lokale Kopie lesen
- lokale Kopie löschen
Martin
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.
- Tom
- 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
Hallo, Rudi.
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.Ich werde mal versuchen, ob ich die Texte in Memofelder packe
Herzlich,
Tom
Tom
- AUGE_OHR
- 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
hi,
such mal nach Opportunistic locking im Forum ...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 ?
gruss by OHR
Jimmy
Jimmy
- Tom
- 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
@Jimmy: OpLocking bei Low-Level-Dateioperationen? Meinst Du wirklich?
Das müsste sich dann auch im normalen DBF-Zugriff zeigen.
Das müsste sich dann auch im normalen DBF-Zugriff zeigen.
Herzlich,
Tom
Tom
- AUGE_OHR
- 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
hi,
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
ausprobieren ...Tom hat geschrieben:@Jimmy: OpLocking bei Low-Level-Dateioperationen? Meinst Du wirklich?
Das müsste sich dann auch im normalen DBF-Zugriff zeigen.
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
Jimmy
- Tom
- 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
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.
Herzlich,
Tom
Tom
-
- 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
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
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
- brandelh
- 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
Hallo,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++.
also wenn du
Code: Alles auswählen
cTxt := memoread(cFileName)
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
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
Hubert
-
- 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
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
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
- brandelh
- 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
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.
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
Hubert